From 9051433707809ed93f503917c671878bc1b001c5 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 21 Nov 2024 12:39:24 -0600 Subject: [PATCH 1/5] Deprecate PPP_CONFIG_DIR for specifying config path --- pyorbital/tests/test_tlefile.py | 31 +++++-------------------------- pyorbital/tlefile.py | 11 +++-------- 2 files changed, 8 insertions(+), 34 deletions(-) diff --git a/pyorbital/tests/test_tlefile.py b/pyorbital/tests/test_tlefile.py index c04572d..d3203b7 100644 --- a/pyorbital/tests/test_tlefile.py +++ b/pyorbital/tests/test_tlefile.py @@ -183,39 +183,18 @@ def test_check_is_platform_supported_unknown(caplog): assert expected3 in logoutput_lines[2] -#def test_get_config_path_ppp_config_set_but_not_pyorbital_future(mock, caplog, monkeypatch): -# """Test getting the config path.""" -# monkeypatch.setenv("SATPY_CONFIG_PATH", "/path/to/satpy/etc") -# monkeypatch.setenv("PPP_CONFIG_DIR", "/path/to/old/mpop/config/dir") -# -# with caplog.at_level(logging.WARNING): -# res = _get_config_path() -# -# log_output = ("The use of PPP_CONFIG_DIR is no longer supported! " + -# "Please use PYORBITAL_CONFIG_PATH if you need a custom config path for pyorbital!") -# assert log_output in caplog.text -# assert res == PKG_CONFIG_DIR - - -def test_get_config_path_ppp_config_set_but_not_pyorbital_is_deprecated(caplog, monkeypatch): - """Test getting the config path. - - Here the case is tested when the new Pyorbital environment variable is not - set but the deprecated (old) Satpy/MPOP one is set. - - """ +def test_get_config_path_ppp_config_set_but_not_pyorbital_future(caplog, monkeypatch): + """Test getting the config path.""" monkeypatch.setenv("SATPY_CONFIG_PATH", "/path/to/satpy/etc") monkeypatch.setenv("PPP_CONFIG_DIR", "/path/to/old/mpop/config/dir") with caplog.at_level(logging.WARNING): res = _get_config_path() - assert res == "/path/to/old/mpop/config/dir" - - log_output = ("The use of PPP_CONFIG_DIR is deprecated and will be removed in version 1.9!" + - " Please use PYORBITAL_CONFIG_PATH if you need a custom config path for pyorbital!") - + log_output = ("The use of PPP_CONFIG_DIR is no longer supported! " + + "Please use PYORBITAL_CONFIG_PATH if you need a custom config path for pyorbital!") assert log_output in caplog.text + assert res == PKG_CONFIG_DIR def test_get_config_path_ppp_config_set_and_pyorbital(caplog, monkeypatch): diff --git a/pyorbital/tlefile.py b/pyorbital/tlefile.py index e8f0305..a9765f4 100644 --- a/pyorbital/tlefile.py +++ b/pyorbital/tlefile.py @@ -63,16 +63,11 @@ class TleDownloadTimeoutError(Exception): def _get_config_path(): """Get the config path for Pyorbital.""" if "PPP_CONFIG_DIR" in os.environ and "PYORBITAL_CONFIG_PATH" not in os.environ: - # XXX: Swap when pyorbital 1.9 is released - #LOGGER.warning( - # "The use of PPP_CONFIG_DIR is no longer supported!" + - # " Please use PYORBITAL_CONFIG_PATH if you need a custom config path for pyorbital!") - #LOGGER.debug("Using the package default for configuration: %s", PKG_CONFIG_DIR) - #return PKG_CONFIG_DIR LOGGER.warning( - "The use of PPP_CONFIG_DIR is deprecated and will be removed in version 1.9!" + + "The use of PPP_CONFIG_DIR is no longer supported!" + " Please use PYORBITAL_CONFIG_PATH if you need a custom config path for pyorbital!") - pyorbital_config_path = os.getenv("PPP_CONFIG_DIR", PKG_CONFIG_DIR) + LOGGER.debug("Using the package default for configuration: %s", PKG_CONFIG_DIR) + return PKG_CONFIG_DIR else: pyorbital_config_path = os.getenv("PYORBITAL_CONFIG_PATH", PKG_CONFIG_DIR) From 95456f013d71dde7732edc65079bcfe32e79ce88 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 21 Nov 2024 12:43:07 -0600 Subject: [PATCH 2/5] Remove deprecated utcnow usage --- pyorbital/tests/test_tlefile.py | 3 ++- pyorbital/tlefile.py | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pyorbital/tests/test_tlefile.py b/pyorbital/tests/test_tlefile.py index d3203b7..967d7f9 100644 --- a/pyorbital/tests/test_tlefile.py +++ b/pyorbital/tests/test_tlefile.py @@ -42,6 +42,7 @@ _get_uris_and_open_func, check_is_platform_supported, read_platform_numbers, + _utcnow, ) LINE0 = "ISS (ZARYA)" @@ -651,7 +652,7 @@ def test_update_db(self): assert data[0][1] == "\n".join((LINE1, LINE2)) # Date when the data were added should be close to current time date_added = datetime.datetime.strptime(data[0][2], ISO_TIME_FORMAT) - now = datetime.datetime.utcnow() + now = _utcnow() assert (now - date_added).total_seconds() < 1.0 # Source of the data assert data[0][3] == "foo" diff --git a/pyorbital/tlefile.py b/pyorbital/tlefile.py index a9765f4..efdc056 100644 --- a/pyorbital/tlefile.py +++ b/pyorbital/tlefile.py @@ -558,7 +558,7 @@ def update_db(self, tle, source): cmd = SATID_VALUES.format(num) epoch = tle.epoch.item().isoformat() tle = "\n".join([tle.line1, tle.line2]) - now = dt.datetime.utcnow().isoformat() + now = _utcnow().isoformat() try: with self.db: self.db.execute(cmd, (epoch, tle, now, source)) @@ -575,7 +575,7 @@ def write_tle_txt(self): return pattern = os.path.join(self.writer_config["output_dir"], self.writer_config["filename_pattern"]) - now = dt.datetime.utcnow() + now = _utcnow() fname = now.strftime(pattern) out_dir = os.path.dirname(fname) if not os.path.exists(out_dir): @@ -589,8 +589,7 @@ def write_tle_txt(self): query = f"SELECT epoch, tle FROM '{satid:d}' ORDER BY epoch DESC LIMIT 1" # nosec epoch, tle = self.db.execute(query).fetchone() # nosec date_epoch = dt.datetime.strptime(epoch, ISO_TIME_FORMAT) - tle_age = ( - dt.datetime.utcnow() - date_epoch).total_seconds() / 3600. + tle_age = (_utcnow() - date_epoch).total_seconds() / 3600. logging.info("Latest TLE for '%s' (%s) is %d hours old.", satid, platform_name, int(tle_age)) data.append(tle) @@ -612,6 +611,9 @@ def table_exists(db, name): return db.execute(query, (name,)).fetchone() is not None # nosec +def _utcnow(): + return dt.datetime.now(tz=dt.timezone.utc).replace(tzinfo=None) + def main(): """Run a test TLE reading.""" tle_data = read("Noaa-19") From e2c6aa20e2e4aacaca1ba02344dbcadcea858107 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 21 Nov 2024 12:44:30 -0600 Subject: [PATCH 3/5] Make pytest fail if warnings are encountered --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 788f65a..7933cfe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -90,3 +90,10 @@ max-complexity = 10 [tool.coverage.run] relative_files = true omit = ["pyorbital/version.py"] + +[tool.pytest.ini_options] +filterwarnings = [ + "error", + "ignore:numpy.ndarray size changed:RuntimeWarning", +] + From 8f1b9b86783f53b28d583467f123a0ceb22763a8 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Fri, 22 Nov 2024 11:01:59 -0600 Subject: [PATCH 4/5] Close TLE files after reading --- pyorbital/tests/test_tlefile.py | 25 ++++++--------- pyorbital/tlefile.py | 56 +++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/pyorbital/tests/test_tlefile.py b/pyorbital/tests/test_tlefile.py index 967d7f9..02bfec5 100644 --- a/pyorbital/tests/test_tlefile.py +++ b/pyorbital/tests/test_tlefile.py @@ -30,6 +30,7 @@ import time import unittest from contextlib import suppress +from tempfile import mkstemp from unittest import mock import pytest @@ -312,42 +313,36 @@ def test_from_line(self): def test_from_file(self): """Test reading and parsing from a file.""" - from os import close, remove, write - from tempfile import mkstemp filehandle, filename = mkstemp() try: - write(filehandle, "\n".join([LINE0, LINE1, LINE2]).encode("utf-8")) - close(filehandle) + os.write(filehandle, "\n".join([LINE0, LINE1, LINE2]).encode("utf-8")) + os.close(filehandle) tle = Tle("ISS (ZARYA)", filename) self.check_example(tle) finally: - remove(filename) + os.remove(filename) def test_from_file_with_hyphenated_platform_name(self): """Test reading and parsing from a file with a slightly different name.""" - from os import close, remove, write - from tempfile import mkstemp filehandle, filename = mkstemp() try: - write(filehandle, NOAA19_3LINES.encode("utf-8")) - close(filehandle) + os.write(filehandle, NOAA19_3LINES.encode("utf-8")) + os.close(filehandle) tle = Tle("NOAA-19", filename) assert tle.satnumber == "33591" finally: - remove(filename) + os.remove(filename) def test_from_file_with_no_platform_name(self): """Test reading and parsing from a file with a slightly different name.""" - from os import close, remove, write - from tempfile import mkstemp filehandle, filename = mkstemp() try: - write(filehandle, NOAA19_2LINES.encode("utf-8")) - close(filehandle) + os.write(filehandle, NOAA19_2LINES.encode("utf-8")) + os.close(filehandle) tle = Tle("NOAA-19", filename) assert tle.satnumber == "33591" finally: - remove(filename) + os.remove(filename) def test_from_mmam_xml(self): """Test reading from an MMAM XML file.""" diff --git a/pyorbital/tlefile.py b/pyorbital/tlefile.py index efdc056..2d35595 100644 --- a/pyorbital/tlefile.py +++ b/pyorbital/tlefile.py @@ -24,7 +24,7 @@ # along with this program. If not, see . """Classes and functions for handling TLE files.""" - +import contextlib import datetime as dt import glob import io @@ -340,33 +340,43 @@ def _get_tles_from_uris(uris, open_func, platform="", only_first=True): tles = [] designator = "1 " + SATELLITES.get(platform, "") for url in uris: - fid = open_func(url) - for l_0 in fid: - tle = "" - l_0 = _decode(l_0) - if l_0.strip() == platform: - l_1 = _decode(next(fid)) - l_2 = _decode(next(fid)) - tle = l_1.strip() + "\n" + l_2.strip() - elif (platform in SATELLITES or not only_first) and l_0.strip().startswith(designator): - l_1 = l_0 - l_2 = _decode(next(fid)) - tle = l_1.strip() + "\n" + l_2.strip() - if platform: - LOGGER.debug("Found platform %s, ID: %s", platform, SATELLITES[platform]) - elif open_func == _dummy_open_stringio and l_0.startswith(designator): - l_1 = l_0 - l_2 = _decode(next(fid)) - tle = l_1.strip() + "\n" + l_2.strip() - if tle: - if only_first: - return tle - tles.append(tle) + with _uri_open(url, open_func) as fid: + for l_0 in fid: + tle = "" + l_0 = _decode(l_0) + if l_0.strip() == platform: + l_1 = _decode(next(fid)) + l_2 = _decode(next(fid)) + tle = l_1.strip() + "\n" + l_2.strip() + elif (platform in SATELLITES or not only_first) and l_0.strip().startswith(designator): + l_1 = l_0 + l_2 = _decode(next(fid)) + tle = l_1.strip() + "\n" + l_2.strip() + if platform: + LOGGER.debug("Found platform %s, ID: %s", platform, SATELLITES[platform]) + elif open_func == _dummy_open_stringio and l_0.startswith(designator): + l_1 = l_0 + l_2 = _decode(next(fid)) + tle = l_1.strip() + "\n" + l_2.strip() + if tle: + if only_first: + return tle + tles.append(tle) if only_first: return "" return tles +@contextlib.contextmanager +def _uri_open(uri, open_func): + file_obj = open_func(uri) + try: + yield file_obj + finally: + if hasattr(file_obj, "close"): + file_obj.close() + + def _decode(itm): if isinstance(itm, str): return itm From 9a1aebe095c64134d3f03caa6b4ab216d028e0ec Mon Sep 17 00:00:00 2001 From: David Hoese Date: Fri, 22 Nov 2024 11:06:53 -0600 Subject: [PATCH 5/5] Fix precommit issues --- pyorbital/tests/test_tlefile.py | 2 +- pyproject.toml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pyorbital/tests/test_tlefile.py b/pyorbital/tests/test_tlefile.py index 02bfec5..705ec75 100644 --- a/pyorbital/tests/test_tlefile.py +++ b/pyorbital/tests/test_tlefile.py @@ -41,9 +41,9 @@ _get_config_path, _get_local_tle_path_from_env, _get_uris_and_open_func, + _utcnow, check_is_platform_supported, read_platform_numbers, - _utcnow, ) LINE0 = "ISS (ZARYA)" diff --git a/pyproject.toml b/pyproject.toml index 7933cfe..a648767 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -96,4 +96,3 @@ filterwarnings = [ "error", "ignore:numpy.ndarray size changed:RuntimeWarning", ] -