diff --git a/benchmarks/time.py b/benchmarks/time.py index 70536285d59..bb2c3cc1103 100644 --- a/benchmarks/time.py +++ b/benchmarks/time.py @@ -15,4 +15,4 @@ def mem_parse_time(): def peakmem_parse_time(): - t = parse_time('1995-12-31 23:59:60') + parse_time('1995-12-31 23:59:60') diff --git a/docs/conf.py b/docs/conf.py index a005671f2ee..75157ece3aa 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -244,6 +244,7 @@ # a list of builtin themes. from sunpy_sphinx_theme.conf import * # NOQA +from sunpy_sphinx_theme.conf import png_icon # NOQA # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/examples/developer_tools/remote_data_manager.py b/examples/developer_tools/remote_data_manager.py index 9e9c7802bae..08e3be834b9 100644 --- a/examples/developer_tools/remote_data_manager.py +++ b/examples/developer_tools/remote_data_manager.py @@ -23,7 +23,7 @@ @manager.require('test_file', ['http://data.sunpy.org/sample-data/predicted-sunspot-radio-flux.txt'], '4c85b04a5528aa97eb84a087450eda0421c71833820576330bba148564089b11') -def test_function(): +def test_function_1(): pass ############################################################################## @@ -35,7 +35,7 @@ def test_function(): @manager.require('test_file', ['http://data.sunpy.org/sample-data/predicted-sunspot-radio-flux.txt'], '4c85b04a5528aa97eb84a087450eda0421c71833820576330bba148564089b11') -def test_function(): +def test_function_2(): return manager.get('test_file') ############################################################################## @@ -43,19 +43,19 @@ def test_function(): # During subsequent calls, no downloading will take place. -print(test_function()) # The file will be downloaded -print(test_function()) # No downloading here +print(test_function_2()) # The file will be downloaded +print(test_function_2()) # No downloading here ############################################################################## # In case the user wants to skip the hash check, there is a helper context manager # `~sunpy.data.data_manager.manager.DataManager.skip_hash_check`. with manager.skip_hash_check(): - print(test_function()) + print(test_function_2()) ############################################################################## # If the user knows the function is going to use a file and want to replace it with another version # they can do that too. with manager.override_file('test_file', 'http://data.sunpy.org/sample-data/AIA20110319_105400_0171.fits'): - print(test_function()) + print(test_function_2()) diff --git a/pyproject.toml b/pyproject.toml index ff42f514513..0a722cffcd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,7 +101,7 @@ exclude=[ select = [ "E", - #"F", + "F", #"W", #"UP", #"PT", @@ -119,17 +119,23 @@ extend-ignore = [ "warnings.warn".msg = "Use sunpy specific warning helpers warn_* from sunpy.utils.exceptions" [tool.ruff.per-file-ignores] -"setup.py" = ["INP001"] # Part of configuration, not a package. +# Part of configuration, not a package. +"setup.py" = ["INP001"] +"conftest.py" = ["INP001"] +# implicit-namespace-package. The examples are not a package. +"docs/*.py" = ["INP001"] + "__init__.py" = ["E402", "F401", "F403"] "test_*.py" = ["B011", "D", "E402", "PGH001", "S101"] -"conftest.py" = ["INP001"] # Part of configuration, not a package. -"docs/*.py" = [ - "INP001", # implicit-namespace-package. The examples are not a package. -] + +# Need to import clients to register them, but don't use them in file +"sunpy/net/__init__.py" = ["F811"] # These files are allowed to use warnings.warn "sunpy/util/exceptions.py" = ["TID251"] "sunpy/util/tests/test_logger.py" = ["TID251"] "sunpy/util/decorators.py" = ["TID251"] +# Notebook config for binder uses undefined variable +".jupyter/jupyter_notebook_config.py" = ["F821"] [tool.ruff.pydocstyle] convention = "numpy" diff --git a/sunpy/coordinates/wcs_utils.py b/sunpy/coordinates/wcs_utils.py index dc89c42994b..bf8897b527c 100644 --- a/sunpy/coordinates/wcs_utils.py +++ b/sunpy/coordinates/wcs_utils.py @@ -13,7 +13,6 @@ from sunpy import log from .frames import ( - BaseCoordinateFrame, Heliocentric, HeliographicCarrington, HeliographicStonyhurst, diff --git a/sunpy/data/sample.py b/sunpy/data/sample.py index 1ba95a97b0e..35d8722d831 100644 --- a/sunpy/data/sample.py +++ b/sunpy/data/sample.py @@ -36,7 +36,7 @@ # file_dict and file_list are not normal variables; see __getattr__() below -__all__ = list(sorted(_SAMPLE_DATA.keys())) + ['download_all', 'file_dict', 'file_list'] +__all__ = list(sorted(_SAMPLE_DATA.keys())) + ['download_all', 'file_dict', 'file_list'] # noqa: F822 # See PEP 562 (https://peps.python.org/pep-0562/) for module-level __dir__() diff --git a/sunpy/database/tests/test_commands.py b/sunpy/database/tests/test_commands.py index 9e2c39c3185..3566be391f1 100644 --- a/sunpy/database/tests/test_commands.py +++ b/sunpy/database/tests/test_commands.py @@ -44,7 +44,7 @@ def test_add_entry_repr(session): expected_repr_result = ( ', ' - 'entry id 5)>'.format(id(session))) + 'entry id 5)>') assert fnmatch.fnmatch(repr_result, expected_repr_result) @@ -129,7 +129,7 @@ def test_remove_entry_repr(session): expected_repr_result = ( ', ' - 'entry DatabaseEntry(id=3))>'.format(id(session))) + 'entry DatabaseEntry(id=3))>') assert fnmatch.fnmatch(repr(RemoveEntry(session, entry)), expected_repr_result) @@ -166,7 +166,7 @@ def test_add_tag_repr(session): ", " - "entry id 12)>".format(id(session))) + "entry id 12)>") assert fnmatch.fnmatch(repr(AddTag(session, entry, tag)), expected_repr_result) @@ -208,7 +208,7 @@ def test_remove_tag_repr(session): ", " - "entry id 8)>".format(id(session))) + "entry id 8)>") assert fnmatch.fnmatch(repr(RemoveTag(session, entry, tag)), expected_repr_result) diff --git a/sunpy/database/tests/test_database.py b/sunpy/database/tests/test_database.py index f19ad3899c7..ac5e2fdb0b3 100644 --- a/sunpy/database/tests/test_database.py +++ b/sunpy/database/tests/test_database.py @@ -515,7 +515,7 @@ def test_vso_query_block_caching_with_overwrite_true_flag(database, # Only downloading for the first query response block with caching disabled - num_of_fits_headers_1 = num_entries_from_vso_query(database, download_qr[:1], + num_entries_from_vso_query(database, download_qr[:1], path=str(tmpdir.join('{file}.type1')), file_pattern=str(tmpdir.join('*.type1')), overwrite=True) @@ -884,7 +884,7 @@ def test_query(filled_database): DatabaseEntry(id=10, tags=[bar])] -def test_fetch_missing_arg(database): +def test_fetch_missing_arg_error(database): with pytest.raises(TypeError): database.fetch() @@ -948,7 +948,7 @@ def test_fetch_missing_arg(database): @pytest.mark.remote_data @pytest.mark.skip -def test_fetch(database, download_query, tmpdir): +def test_fetch2(database, download_query, tmpdir): assert len(database) == 0 database.default_waveunit = 'angstrom' database.fetch(*download_query, path=str(tmpdir.join('{file}.fits'))) diff --git a/sunpy/io/file_tools.py b/sunpy/io/file_tools.py index 64c2d30d8a9..f43644b1e7c 100644 --- a/sunpy/io/file_tools.py +++ b/sunpy/io/file_tools.py @@ -1,4 +1,4 @@ -from _file_tools import * # noqa: F401 +from _file_tools import * # noqa: F403 from sunpy.util.exceptions import warn_deprecated from . import _file_tools diff --git a/sunpy/io/jp2.py b/sunpy/io/jp2.py index 04b7a0c1405..ee70601144d 100644 --- a/sunpy/io/jp2.py +++ b/sunpy/io/jp2.py @@ -1,4 +1,4 @@ -from _jp2 import * # noqa: F401 +from _jp2 import * # noqa: F403 from sunpy.util.exceptions import warn_deprecated from . import _jp2 diff --git a/sunpy/io/special/genx.py b/sunpy/io/special/genx.py index 44e17f0edc4..e8726957bec 100644 --- a/sunpy/io/special/genx.py +++ b/sunpy/io/special/genx.py @@ -12,6 +12,27 @@ # This class has been copied from the Python 3.11 stdlib xdrlib.py file under # the terms of the PSF licence 2.0 +class Error(Exception): + """Exception class for this module. Use: + except xdrlib.Error as var: + # var has the Error instance for the exception + Public ivars: + msg -- contains the message + """ + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + return repr(self.msg) + + def __str__(self): + return str(self.msg) + + +class ConversionError(Error): + pass + + class Unpacker: """Unpacks various data representations from the given buffer.""" diff --git a/sunpy/io/tests/test_filetools.py b/sunpy/io/tests/test_filetools.py index c14aed5e457..e60a239a4c2 100644 --- a/sunpy/io/tests/test_filetools.py +++ b/sunpy/io/tests/test_filetools.py @@ -116,15 +116,6 @@ def test_write_file_ana(): os.remove("ana_test_write.fz") -@skip_glymur -def test_read_file_header_jp2(): - hlist = sunpy.io.read_file_header(os.path.join(sunpy.data.test.rootdir, - "2013_06_24__17_31_30_84__SDO_AIA_AIA_193.jp2")) - assert isinstance(hlist, list) - assert len(hlist) == 1 - assert isinstance(hlist[0], sunpy.io.header.FileHeader) - - @pytest.mark.parametrize('fname', ['aia_171_image.fits', pathlib.Path('aia_171_image.fits')]) def test_write_file_fits(fname): @@ -147,32 +138,3 @@ def test_write_file_fits_bytes(): assert np.all(np.equal(outpair[0], aiapair[0])) assert outpair[1] == aiapair[1] os.remove("aia_171_image_bytes.fits") - - -@skip_ana -def test_read_file_ana(): - ana_data = sunpy.io.read_file(os.path.join(sunpy.data.test.rootdir, "test_ana.fz")) - assert isinstance(ana_data, list) - assert len(ana_data) == 1 - assert len(ana_data[0]) == 2 - assert isinstance(ana_data[0][0], np.ndarray) - assert isinstance(ana_data[0][1], sunpy.io.header.FileHeader) - - -@skip_ana -def test_read_file__header_ana(): - ana_data = sunpy.io.read_file_header(os.path.join(sunpy.data.test.rootdir, "test_ana.fz")) - assert isinstance(ana_data, list) - assert len(ana_data) == 1 - assert isinstance(ana_data[0], sunpy.io.header.FileHeader) - - -@skip_ana -def test_write_file_ana(): - ana = sunpy.io.read_file(os.path.join(sunpy.data.test.rootdir, "test_ana.fz"))[0] - sunpy.io.write_file("ana_test_write.fz", ana[0], str(ana[1])) - assert os.path.exists("ana_test_write.fz") - outpair = sunpy.io.read_file(os.path.join(sunpy.data.test.rootdir, "test_ana.fz")) - assert np.all(np.equal(outpair[0][1], ana[1])) - assert outpair[0][1] == ana[1] - os.remove("ana_test_write.fz") diff --git a/sunpy/map/tests/test_header_helper.py b/sunpy/map/tests/test_header_helper.py index 47643a8f1ae..0fdf1631c74 100644 --- a/sunpy/map/tests/test_header_helper.py +++ b/sunpy/map/tests/test_header_helper.py @@ -233,17 +233,17 @@ def test_invalid_inputs(map_data, hcc_coord, hpc_coord_notime, hpc_coord): # Check arguments not given as astropy Quantities with pytest.raises(TypeError): - header = make_fitswcs_header(map_data, hpc_coord, reference_pixel=[0, 0]) + make_fitswcs_header(map_data, hpc_coord, reference_pixel=[0, 0]) with pytest.raises(TypeError): - header = make_fitswcs_header(map_data, hpc_coord, scale=[0, 0]) + make_fitswcs_header(map_data, hpc_coord, scale=[0, 0]) # Check arguments of reference_pixel and scale have to be given in astropy units of pix, and arcsec/pix with pytest.raises(u.UnitsError): - header = make_fitswcs_header(map_data, hpc_coord, reference_pixel=u.Quantity([0, 0])) + make_fitswcs_header(map_data, hpc_coord, reference_pixel=u.Quantity([0, 0])) with pytest.raises(u.UnitsError): - header = make_fitswcs_header(map_data, hpc_coord, scale=u.Quantity([0, 0])) + make_fitswcs_header(map_data, hpc_coord, scale=u.Quantity([0, 0])) with pytest.raises(u.UnitsError): - header = make_fitswcs_header(map_data, hpc_coord, scale=u.Quantity([0, 0]*u.arcsec)) + make_fitswcs_header(map_data, hpc_coord, scale=u.Quantity([0, 0]*u.arcsec)) @pytest.mark.parametrize('frame', ['carrington', 'stonyhurst']) diff --git a/sunpy/map/tests/test_map_factory.py b/sunpy/map/tests/test_map_factory.py index 4c2cd1dd5a1..49e6d1a9040 100644 --- a/sunpy/map/tests/test_map_factory.py +++ b/sunpy/map/tests/test_map_factory.py @@ -185,7 +185,7 @@ def test_errors(tmpdir): p = tmpdir.mkdir("sub").join("hello.fits") p.write("content") files = [AIA_171_IMAGE, p.strpath] - with pytest.raises(OSError, match=(fr"Failed to read *")): + with pytest.raises(OSError, match=(r"Failed to read *")): sunpy.map.Map(files) diff --git a/sunpy/map/tests/test_mapsequence.py b/sunpy/map/tests/test_mapsequence.py index 17ab1e27820..77d19d8392c 100644 --- a/sunpy/map/tests/test_mapsequence.py +++ b/sunpy/map/tests/test_mapsequence.py @@ -142,15 +142,15 @@ def test_repr(mapsequence_all_the_same, mapsequence_different_maps): for mapsequence of same maps as well that of different maps. """ # Test the case of MapSequence having same maps - expected_out = f'MapSequence of 2 elements, with maps from AIAMap' + expected_out = 'MapSequence of 2 elements, with maps from AIAMap' obtained_out = repr(mapsequence_all_the_same) assert obtained_out.startswith(object.__repr__(mapsequence_all_the_same)) assert len(mapsequence_all_the_same) == 2 assert expected_out in obtained_out # Test the case of MapSequence having different maps - expected_out1 = f'MapSequence of 2 elements, with maps from AIAMap, EITMap' - expected_out2 = f'MapSequence of 2 elements, with maps from EITMap, AIAMap' + expected_out1 = 'MapSequence of 2 elements, with maps from AIAMap, EITMap' + expected_out2 = 'MapSequence of 2 elements, with maps from EITMap, AIAMap' obtained_out = repr(mapsequence_different_maps) assert obtained_out.startswith(object.__repr__(mapsequence_different_maps)) assert len(mapsequence_different_maps) == 2 diff --git a/sunpy/net/dataretriever/sources/tests/test_goes_ud.py b/sunpy/net/dataretriever/sources/tests/test_goes_ud.py index f041e552dac..96c5b09d958 100644 --- a/sunpy/net/dataretriever/sources/tests/test_goes_ud.py +++ b/sunpy/net/dataretriever/sources/tests/test_goes_ud.py @@ -164,7 +164,7 @@ def test_resolution_attrs(LCClient): # check is incorrect resolution attrs passed with pytest.raises(RuntimeError): - qr_wrong_resolution = LCClient.search(Time('2012/10/4 20:20', '2012/10/4 21:00'), Instrument('XRS'), a.Resolution.ctime) + LCClient.search(Time('2012/10/4 20:20', '2012/10/4 21:00'), Instrument('XRS'), a.Resolution.ctime) @pytest.mark.remote_data diff --git a/sunpy/net/hek2vso/tests/test_hek2vso.py b/sunpy/net/hek2vso/tests/test_hek2vso.py index ee6269164a1..aff0fc3f2a9 100644 --- a/sunpy/net/hek2vso/tests/test_hek2vso.py +++ b/sunpy/net/hek2vso/tests/test_hek2vso.py @@ -142,7 +142,7 @@ def test_full_query(h2v_client, hek_client): @pytest.mark.remote_data def test_quick_clean(h2v_client, hek_client): h2v = h2v_client - h2v_q = h2v.full_query( + h2v.full_query( (a.Time(startTime, endTime), a.hek.EventType(eventType), a.hek.FL.PeakFlux > 1000) ) diff --git a/sunpy/net/helio/__init__.py b/sunpy/net/helio/__init__.py index 00779eba8ac..02b4af05d0c 100644 --- a/sunpy/net/helio/__init__.py +++ b/sunpy/net/helio/__init__.py @@ -6,4 +6,4 @@ from .hec import * from .parser import * -__all__ = ['HECClient', 'HECResponse', 'Chaincode'] +__all__ = ['HECClient', 'HECResponse', 'Chaincode'] # noqa: F405 diff --git a/sunpy/net/jsoc/jsoc.py b/sunpy/net/jsoc/jsoc.py index 0451e7c8786..a381f1e8226 100644 --- a/sunpy/net/jsoc/jsoc.py +++ b/sunpy/net/jsoc/jsoc.py @@ -483,7 +483,7 @@ def get_request(self, requests, path=None, overwrite=False, progress=True, # Private communication from JSOC say we should not use more than one connection. max_splits = kwargs.get('max_splits', 1) if max_splits != 1: - log.info(f"Setting max_splits to it's maximum allowed value of 1 for requests made by the JSOCClient.") + log.info("Setting max_splits to it's maximum allowed value of 1 for requests made by the JSOCClient.") max_splits = 1 # Convert Responses to a list if not already @@ -533,7 +533,7 @@ def get_request(self, requests, path=None, overwrite=False, progress=True, dl_set = False # Private communication from JSOC say we should not use more than one connection. if max_conn != self.default_max_conn: - log.info(f"Setting max parallel downloads to 1 for the JSOC client.") + log.info("Setting max parallel downloads to 1 for the JSOC client.") downloader = Downloader(max_conn=max_conn, progress=progress, overwrite=overwrite, max_splits=max_splits) urls = [] for request in requests: diff --git a/sunpy/net/scraper.py b/sunpy/net/scraper.py index 6d5d87a83bc..4e0bede8f1b 100644 --- a/sunpy/net/scraper.py +++ b/sunpy/net/scraper.py @@ -343,7 +343,7 @@ def _ftpfileslist(self, timerange): if self._check_timerange(fullpath, timerange): filesurls.append(fullpath) - filesurls = [f'ftp://' + "{0.netloc}{0.path}".format(urlsplit(url)) + filesurls = ['ftp://' + "{0.netloc}{0.path}".format(urlsplit(url)) for url in filesurls] return filesurls diff --git a/sunpy/net/tests/test_attr.py b/sunpy/net/tests/test_attr.py index 7bfcdcccb56..83c61ea1fa1 100644 --- a/sunpy/net/tests/test_attr.py +++ b/sunpy/net/tests/test_attr.py @@ -94,7 +94,7 @@ class TestAttr(attr.Attr): @pytest.mark.parametrize("different_type", [ int, str, float, list, set, tuple, dict, object ]) -def test_empty(different_type): +def test_empty_type(different_type): attr_ = attr.Attr() assert attr_ != different_type() diff --git a/sunpy/physics/tests/test_differential_rotation.py b/sunpy/physics/tests/test_differential_rotation.py index 11051bbb75a..651cdf25c1f 100644 --- a/sunpy/physics/tests/test_differential_rotation.py +++ b/sunpy/physics/tests/test_differential_rotation.py @@ -127,7 +127,7 @@ def test_rigid(seconds_per_day): def test_fail(seconds_per_day): with pytest.raises(ValueError): - rot = diff_rot(10 * seconds_per_day, 30 * u.deg, rot_type='garbage') + diff_rot(10 * seconds_per_day, 30 * u.deg, rot_type='garbage') def test_solar_rotate_coordinate(): diff --git a/sunpy/visualization/colormaps/__init__.py b/sunpy/visualization/colormaps/__init__.py index fbe2fb3a5b7..5b17e0b5836 100644 --- a/sunpy/visualization/colormaps/__init__.py +++ b/sunpy/visualization/colormaps/__init__.py @@ -11,5 +11,5 @@ """ from sunpy.visualization.colormaps.cm import * -for cmname in cmlist.keys(): +for cmname in cmlist.keys(): # noqa: F405 __doc__ += f"\n* '{cmname}'\n" diff --git a/sunpy/visualization/visualization.py b/sunpy/visualization/visualization.py index 8595ccd97cd..ff2d495de16 100644 --- a/sunpy/visualization/visualization.py +++ b/sunpy/visualization/visualization.py @@ -42,15 +42,15 @@ def axis_labels_from_ctype(ctype, unit): """ ctype_short = ctype[:4] - labels = {'HGLN': f'Heliographic Longitude', - 'CRLN': f'Carrington Longitude', - 'HPLN': f'Helioprojective Longitude (Solar-X)', - 'SOLX': f'Heliocentric X', - - 'HGLT': f'Latitude', - 'CRLT': f'Latitude', - 'HPLT': f'Helioprojective Latitude (Solar-Y)', - 'SOLY': f'Heliocentric Y'} + labels = {'HGLN': 'Heliographic Longitude', + 'CRLN': 'Carrington Longitude', + 'HPLN': 'Helioprojective Longitude (Solar-X)', + 'SOLX': 'Heliocentric X', + + 'HGLT': 'Latitude', + 'CRLT': 'Latitude', + 'HPLT': 'Helioprojective Latitude (Solar-Y)', + 'SOLY': 'Heliocentric Y'} label = labels.get(ctype_short, f"{ctype}") if unit is not None: