From f807d8b6ac46f7b65cbdfa7e7a51dd061b8bbf78 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Wed, 22 Nov 2023 15:18:18 -0800 Subject: [PATCH 1/6] update requirements*.txt --- requirements-dev.txt | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index e4bfab5..1ccfbcc 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,19 +1,20 @@ # DO NOT EDIT THIS FILE DIRECTLY - use ./script/update-requirements to update -Pygments==2.16.1 -black==23.9.1 +Pygments==2.17.2 +black==23.11.0 build==1.0.3 -certifi==2023.7.22 +certifi==2023.11.17 cffi==1.16.0 -charset-normalizer==3.3.0 +charset-normalizer==3.3.2 click==8.1.7 cmarkgfm==2022.10.27 coverage==7.3.2 docutils==0.20.1 +exceptiongroup==1.2.0 importlib-metadata==6.8.0 iniconfig==2.0.0 isort==5.12.0 jaraco.classes==3.3.0 -keyring==24.2.0 +keyring==24.3.0 markdown-it-py==3.0.0 mdurl==0.1.2 more-itertools==10.1.0 @@ -22,7 +23,7 @@ nh3==0.2.14 packaging==23.2 pathspec==0.11.2 pkginfo==1.9.6 -platformdirs==3.11.0 +platformdirs==4.0.0 pluggy==1.3.0 pprintpp==0.4.0 pycountry-convert==0.7.2 @@ -31,17 +32,17 @@ pycparser==2.21 pyflakes==3.1.0 pyproject_hooks==1.0.0 pytest-cov==4.1.0 -pytest-mock==3.11.1 +pytest-mock==3.12.0 pytest-network==0.0.1 -pytest==7.4.2 +pytest==7.4.3 readme-renderer==42.0 repoze.lru==0.7 requests-toolbelt==1.0.0 requests==2.31.0 rfc3986==2.0.0 -rich==13.6.0 -setuptools==68.2.2 +rich==13.7.0 +tomli==2.0.1 twine==4.0.2 -urllib3==2.0.6 -wheel==0.41.2 +typing_extensions==4.8.0 +urllib3==2.1.0 zipp==3.17.0 From 0332b34f7252146af07b5f2902b8c6847036b7f4 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Wed, 22 Nov 2023 18:06:10 -0800 Subject: [PATCH 2/6] deprecation.deprecated, use official mechinism for deprecations --- octodns/deprecation.py | 9 +++++++++ octodns/processor/spf.py | 3 ++- octodns/provider/yaml.py | 5 +++-- octodns/record/ds.py | 5 +++-- octodns/record/geo.py | 5 +++-- octodns/record/spf.py | 3 ++- octodns/zone.py | 6 ++++-- tests/test_octodns_record_geo.py | 18 ------------------ 8 files changed, 26 insertions(+), 28 deletions(-) create mode 100644 octodns/deprecation.py diff --git a/octodns/deprecation.py b/octodns/deprecation.py new file mode 100644 index 0000000..bdb1e88 --- /dev/null +++ b/octodns/deprecation.py @@ -0,0 +1,9 @@ +# +# +# + +from warnings import warn + + +def deprecated(message, stacklevel=2): + warn(message, DeprecationWarning, stacklevel=stacklevel) diff --git a/octodns/processor/spf.py b/octodns/processor/spf.py index 0d86d5e..29137cd 100644 --- a/octodns/processor/spf.py +++ b/octodns/processor/spf.py @@ -10,6 +10,7 @@ from dns.resolver import Answer from octodns.record.base import Record +from ..deprecation import deprecated from .base import BaseProcessor, ProcessorException @@ -55,7 +56,7 @@ class SpfDnsLookupProcessor(BaseProcessor): def __init__(self, name): self.log.debug(f"SpfDnsLookupProcessor: {name}") - self.log.warning( + deprecated( 'SpfDnsLookupProcessor is DEPRECATED in favor of the version relocated into octodns-spf and will be removed in 2.0' ) super().__init__(name) diff --git a/octodns/provider/yaml.py b/octodns/provider/yaml.py index 23e65ef..a3db28e 100644 --- a/octodns/provider/yaml.py +++ b/octodns/provider/yaml.py @@ -7,6 +7,7 @@ from collections import defaultdict from os import listdir, makedirs from os.path import isdir, isfile, join +from ..deprecation import deprecated from ..record import Record from ..yaml import safe_dump, safe_load from . import ProviderException @@ -466,6 +467,6 @@ class SplitYamlProvider(YamlProvider): } ) super().__init__(id, directory, *args, **kwargs) - self.log.warning( - '__init__: DEPRECATED use YamlProvider with split_extension, split_catchall, and disable_zonefile instead, will go away in v2.0' + deprecated( + 'SplitYamlProvider is DEPRECATED, use YamlProvider with split_extension, split_catchall, and disable_zonefile instead, will go away in v2.0' ) diff --git a/octodns/record/ds.py b/octodns/record/ds.py index fe25803..d2f1763 100644 --- a/octodns/record/ds.py +++ b/octodns/record/ds.py @@ -4,6 +4,7 @@ from logging import getLogger +from ..deprecation import deprecated from ..equality import EqualityTupleMixin from .base import Record, ValuesMixin from .rr import RrParseError @@ -48,8 +49,8 @@ class DsValue(EqualityTupleMixin, dict): # it is safe to assume if public_key or flags are defined then it is "old" style # A DS record without public_key doesn't make any sense and shouldn't have validated previously if "public_key" in value or "flags" in value: - cls.log.warning( - '"algorithm", "flags", "public_key", and "protocol" support is DEPRECATED and will be removed in 2.0' + deprecated( + 'DS properties "algorithm", "flags", "public_key", and "protocol" support is DEPRECATED and will be removed in 2.0' ) try: int(value['flags']) diff --git a/octodns/record/geo.py b/octodns/record/geo.py index af8337c..60dab30 100644 --- a/octodns/record/geo.py +++ b/octodns/record/geo.py @@ -5,6 +5,7 @@ import re from logging import getLogger +from ..deprecation import deprecated from ..equality import EqualityTupleMixin from .base import ValuesMixin from .change import Update @@ -141,8 +142,8 @@ class _GeoMixin(ValuesMixin): reasons = super().validate(name, fqdn, data) try: geo = dict(data['geo']) - cls.log.warning( - 'NOTICE: `geo` record support is deprecated and should be migrated to `dynamic` records' + deprecated( + '`geo` records are DEPRECATED. `dynamic` records should be used instead. Will be removed in 2.0' ) for code, values in geo.items(): reasons.extend(GeoValue._validate_geo(code)) diff --git a/octodns/record/spf.py b/octodns/record/spf.py index 9eb7a4a..57c13de 100644 --- a/octodns/record/spf.py +++ b/octodns/record/spf.py @@ -2,6 +2,7 @@ # # +from ..deprecation import deprecated from .base import Record from .chunked import _ChunkedValue, _ChunkedValuesMixin @@ -12,7 +13,7 @@ class SpfRecord(_ChunkedValuesMixin, Record): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.log.warning( + deprecated( 'The SPF record type is DEPRECATED in favor of TXT values and will become an ValidationError in 2.0' ) diff --git a/octodns/zone.py b/octodns/zone.py index a1ee51d..fe604f7 100644 --- a/octodns/zone.py +++ b/octodns/zone.py @@ -6,6 +6,7 @@ import re from collections import defaultdict from logging import getLogger +from .deprecation import deprecated from .idna import idna_decode, idna_encode from .record import Create, Delete @@ -197,8 +198,9 @@ class Zone(object): # TODO: delete this at v2.0.0rc0 def _remove_record(self, record): - self.log.warning( - '_remove_record: method has been deprecated, used remove_record instead' + deprecated( + '_remove_record has been deprecated, used remove_record instead. Will be removed in 2.0', + stacklevel=3, ) return self.remove_record(record) diff --git a/tests/test_octodns_record_geo.py b/tests/test_octodns_record_geo.py index 420570e..6481b5f 100644 --- a/tests/test_octodns_record_geo.py +++ b/tests/test_octodns_record_geo.py @@ -213,24 +213,6 @@ class TestRecordGeoCodes(TestCase): self.assertTrue(c >= b) def test_validation(self): - with self.assertLogs('Record', level='WARNING') as cm: - Record.new( - self.zone, - '', - { - 'geo': {'NA': ['1.2.3.5'], 'NA-US': ['1.2.3.5', '1.2.3.6']}, - 'type': 'A', - 'ttl': 600, - 'value': '1.2.3.4', - }, - ) - self.assertEqual( - [ - 'WARNING:Record:NOTICE: `geo` record support is deprecated and should be migrated to `dynamic` records' - ], - cm.output, - ) - # invalid ip address with self.assertRaises(ValidationError) as ctx: Record.new( From 142eaa709fde3017e90a38098f3a68e2ce9d8989 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Wed, 22 Nov 2023 18:16:59 -0800 Subject: [PATCH 3/6] tell pytest to ignore all of our internal 2.0 deprecated warnings --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index d8a2a3d..605ed54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,4 +9,7 @@ known_first_party="octodns" line_length=80 [tool.pytest.ini_options] +filterwarnings = [ + 'ignore:.*DEPRECATED.*2.0', +] pythonpath = "." From e03adfceda4ad4aac1c37bd39c28958f8f3fb0f4 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Wed, 22 Nov 2023 18:31:52 -0800 Subject: [PATCH 4/6] Address datetime.utcnow deprecation in py 3.12 --- octodns/processor/meta.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/octodns/processor/meta.py b/octodns/processor/meta.py index ee56ef8..0389388 100644 --- a/octodns/processor/meta.py +++ b/octodns/processor/meta.py @@ -10,6 +10,14 @@ from .. import __version__ from ..record import Record from .base import BaseProcessor +# TODO: remove once we require python >= 3.11 +try: # pragma: no cover + from datetime import UTC +except ImportError: # pragma: no cover + from datetime import timedelta, timezone + + UTC = timezone(timedelta()) + def _keys(values): return set(v.split('=', 1)[0] for v in values) @@ -55,7 +63,7 @@ class MetaProcessor(BaseProcessor): @classmethod def now(cls): - return datetime.utcnow().isoformat() + return datetime.now(UTC).isoformat() @classmethod def uuid(cls): From d886244399caa84ae995819b3baa0efc32443c84 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sun, 26 Nov 2023 12:01:08 -0800 Subject: [PATCH 5/6] Warnings are errors during tests --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index d8a2a3d..72d1688 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,4 +9,7 @@ known_first_party="octodns" line_length=80 [tool.pytest.ini_options] +filterwarnings = [ + 'error', +] pythonpath = "." From f776fc6e65ce27632c087d6abdba145863911ec5 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sun, 26 Nov 2023 13:21:02 -0800 Subject: [PATCH 6/6] essentially ditch stacklevel/context for deprecation of config thigns (it's not useful) --- octodns/processor/spf.py | 3 ++- octodns/provider/yaml.py | 3 ++- octodns/record/ds.py | 3 ++- octodns/record/geo.py | 3 ++- octodns/record/spf.py | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/octodns/processor/spf.py b/octodns/processor/spf.py index 29137cd..fbd4575 100644 --- a/octodns/processor/spf.py +++ b/octodns/processor/spf.py @@ -57,7 +57,8 @@ class SpfDnsLookupProcessor(BaseProcessor): def __init__(self, name): self.log.debug(f"SpfDnsLookupProcessor: {name}") deprecated( - 'SpfDnsLookupProcessor is DEPRECATED in favor of the version relocated into octodns-spf and will be removed in 2.0' + 'SpfDnsLookupProcessor is DEPRECATED in favor of the version relocated into octodns-spf and will be removed in 2.0', + stacklevel=99, ) super().__init__(name) diff --git a/octodns/provider/yaml.py b/octodns/provider/yaml.py index a3db28e..70c6f8c 100644 --- a/octodns/provider/yaml.py +++ b/octodns/provider/yaml.py @@ -468,5 +468,6 @@ class SplitYamlProvider(YamlProvider): ) super().__init__(id, directory, *args, **kwargs) deprecated( - 'SplitYamlProvider is DEPRECATED, use YamlProvider with split_extension, split_catchall, and disable_zonefile instead, will go away in v2.0' + 'SplitYamlProvider is DEPRECATED, use YamlProvider with split_extension, split_catchall, and disable_zonefile instead, will go away in v2.0', + stacklevel=99, ) diff --git a/octodns/record/ds.py b/octodns/record/ds.py index d2f1763..2e8bfe4 100644 --- a/octodns/record/ds.py +++ b/octodns/record/ds.py @@ -50,7 +50,8 @@ class DsValue(EqualityTupleMixin, dict): # A DS record without public_key doesn't make any sense and shouldn't have validated previously if "public_key" in value or "flags" in value: deprecated( - 'DS properties "algorithm", "flags", "public_key", and "protocol" support is DEPRECATED and will be removed in 2.0' + 'DS properties "algorithm", "flags", "public_key", and "protocol" support is DEPRECATED and will be removed in 2.0', + stacklevel=99, ) try: int(value['flags']) diff --git a/octodns/record/geo.py b/octodns/record/geo.py index 60dab30..ade3806 100644 --- a/octodns/record/geo.py +++ b/octodns/record/geo.py @@ -143,7 +143,8 @@ class _GeoMixin(ValuesMixin): try: geo = dict(data['geo']) deprecated( - '`geo` records are DEPRECATED. `dynamic` records should be used instead. Will be removed in 2.0' + '`geo` records are DEPRECATED. `dynamic` records should be used instead. Will be removed in 2.0', + stacklevel=99, ) for code, values in geo.items(): reasons.extend(GeoValue._validate_geo(code)) diff --git a/octodns/record/spf.py b/octodns/record/spf.py index 57c13de..f0bd824 100644 --- a/octodns/record/spf.py +++ b/octodns/record/spf.py @@ -14,7 +14,8 @@ class SpfRecord(_ChunkedValuesMixin, Record): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) deprecated( - 'The SPF record type is DEPRECATED in favor of TXT values and will become an ValidationError in 2.0' + 'The SPF record type is DEPRECATED in favor of TXT values and will become an ValidationError in 2.0', + stacklevel=99, )