From bd135d43f1720147abf875fc7a5b1b313cf50394 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Wed, 25 Sep 2019 14:48:37 +0200 Subject: [PATCH 1/9] Add attr.__version_info__ This allows users to check for features and avoid deprecation warnings without breaking backward compatibility. --- docs/api.rst | 24 ++++++++++++ src/attr/__init__.py | 3 ++ src/attr/_version.py | 85 +++++++++++++++++++++++++++++++++++++++++++ tests/test_version.py | 49 +++++++++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 src/attr/_version.py create mode 100644 tests/test_version.py diff --git a/docs/api.rst b/docs/api.rst index f68aaa07d..672d2d46a 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -506,7 +506,31 @@ Converters Deprecated APIs --------------- +.. _version-info: + +To help you writing backward compatible code that doesn't throw warnings on modern releases, the ``attr`` module has an ``__version_info__`` attribute as of version 19.2.0. +It behaves similarly to `sys.version_info` and is an instance of `VersionInfo`: + +.. autoclass:: VersionInfo + + With its help you can write code like this: + + >>> if getattr(attr, "__version_info__", (0,)) >= (19, 2): + ... cmp_off = {"eq": False} + ... else: + ... cmp_off= {"cmp": False} + >>> cmp_off == {"eq": False} + True + >>> @attr.s(**cmp_off) + ... class C(object): + ... pass + + +---- + The serious business aliases used to be called ``attr.attributes`` and ``attr.attr``. There are no plans to remove them but they shouldn't be used in new code. +The ``cmp`` argument to both `attr.s` and `attr.ib` has been deprecated in 19.2 and shouldn't be used. + .. autofunction:: assoc diff --git a/src/attr/__init__.py b/src/attr/__init__.py index cf322d04d..c28f0568b 100644 --- a/src/attr/__init__.py +++ b/src/attr/__init__.py @@ -16,9 +16,11 @@ make_class, validate, ) +from ._version import VersionInfo __version__ = "19.2.0.dev0" +__version_info__ = VersionInfo._from_version_string(__version__) __title__ = "attrs" __description__ = "Classes Without Boilerplate" @@ -37,6 +39,7 @@ ib = attr = attrib dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) + __all__ = [ "Attribute", "Factory", diff --git a/src/attr/_version.py b/src/attr/_version.py new file mode 100644 index 000000000..14ad1012b --- /dev/null +++ b/src/attr/_version.py @@ -0,0 +1,85 @@ +from __future__ import absolute_import, division, print_function + +from functools import total_ordering + +from ._funcs import astuple +from ._make import attrib, attrs + + +@total_ordering +@attrs(eq=False, order=False, slots=True, frozen=True) +class VersionInfo(object): + """ + A version object that can be compared to tuple of length 1–4: + + >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2) + True + >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1) + True + >>> vi = attr.VersionInfo(19, 2, 0, "final") + >>> vi < (19, 1, 1) + False + >>> vi < (19,) + False + >>> vi == (19, 2,) + True + >>> vi == (19, 2, 1) + False + + .. versionadded:: 19.2 + """ + + year = attrib(type=int) + minor = attrib(type=int) + micro = attrib(type=int) + releaselevel = attrib(type=str) + + @classmethod + def _from_version_string(cls, s): + """ + Parse *s* and return a _VersionInfo. + """ + v = s.split(".") + if len(v) == 3: + v.append("final") + + return cls( + year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3] + ) + + def _ensure_tuple(self, other): + """ + Ensure *other* is a tuple of a valid length. + + Returns a possibly transformed *other* and ourselves as a tuple of + the same length as *other*. + """ + + if self.__class__ is other.__class__: + other = astuple(other) + + if not isinstance(other, tuple): + raise NotImplementedError + + if not (1 <= len(other) <= 4): + raise NotImplementedError + + return astuple(self)[: len(other)], other + + def __eq__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + return us == them + + def __lt__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't + # have to do anything special with releaselevel for now. + return us < them diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 000000000..d35bc7a69 --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,49 @@ +from __future__ import absolute_import, division, print_function + +import pytest + +from attr import VersionInfo +from attr._compat import PY2 + + +@pytest.fixture(name="vi") +def fixture_vi(): + return VersionInfo(19, 2, 0, "final") + + +class TestVersionInfo: + def test_from_string_no_releaselevel(self, vi): + """ + If there is no suffix, the releaselevel becomes "final" by default. + """ + assert vi == VersionInfo._from_version_string("19.2.0") + + @pytest.mark.parametrize("other", [(), (19, 2, 0, "final", "garbage")]) + def test_wrong_len(self, vi, other): + """ + Comparing with a tuple that has the wrong length raises an error. + """ + assert vi != other + + if not PY2: + with pytest.raises(TypeError): + vi < other + + @pytest.mark.parametrize("other", [[19, 2, 0, "final"]]) + def test_wrong_type(self, vi, other): + """ + Only compare to other VersionInfos or tuples. + """ + assert vi != other + + def test_order(self, vi): + """ + Ordering works as expected. + """ + assert vi < (20,) + assert vi < (19, 2, 1) + assert vi > (0,) + assert vi <= (19, 2) + assert vi >= (19, 2) + assert vi > (19, 2, 0, "dev0") + assert vi < (19, 2, 0, "post1") From fb5728a357d232ca34e98a3a2f25a81816e22f71 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Wed, 25 Sep 2019 16:20:18 +0200 Subject: [PATCH 2/9] Add newsfragment --- changelog.d/580.change.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog.d/580.change.rst diff --git a/changelog.d/580.change.rst b/changelog.d/580.change.rst new file mode 100644 index 000000000..74a993457 --- /dev/null +++ b/changelog.d/580.change.rst @@ -0,0 +1,2 @@ +Added ``attr.__version_info__`` that can be used to reliably check the version of ``attrs`` and write forward- and backward-compatible code. +Please check out the `section on deprecated APIs `_ on how to use it. From 25735e7a3c5d07d85a45abc86bafda6303902396 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Wed, 25 Sep 2019 16:30:36 +0200 Subject: [PATCH 3/9] Stay ASCII --- src/attr/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attr/_version.py b/src/attr/_version.py index 14ad1012b..014e78a1b 100644 --- a/src/attr/_version.py +++ b/src/attr/_version.py @@ -10,7 +10,7 @@ @attrs(eq=False, order=False, slots=True, frozen=True) class VersionInfo(object): """ - A version object that can be compared to tuple of length 1–4: + A version object that can be compared to tuple of length 1--4: >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2) True From 516fc28186658fd34ebe8b756832a10fcf5aa5c2 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Wed, 25 Sep 2019 19:05:01 +0200 Subject: [PATCH 4/9] Typo --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 672d2d46a..ebe2a8138 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -518,7 +518,7 @@ It behaves similarly to `sys.version_info` and is an instance of `VersionInfo`: >>> if getattr(attr, "__version_info__", (0,)) >= (19, 2): ... cmp_off = {"eq": False} ... else: - ... cmp_off= {"cmp": False} + ... cmp_off = {"cmp": False} >>> cmp_off == {"eq": False} True >>> @attr.s(**cmp_off) From f8f3496d049e16ef84cda87c49a33f36f028409f Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Thu, 26 Sep 2019 07:01:02 +0200 Subject: [PATCH 5/9] Add stubs for _version.py --- src/attr/__init__.pyi | 2 ++ src/attr/_version.pyi | 5 +++++ tox.ini | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 src/attr/_version.pyi diff --git a/src/attr/__init__.pyi b/src/attr/__init__.pyi index 03bcf89f1..1e7bf26a1 100644 --- a/src/attr/__init__.pyi +++ b/src/attr/__init__.pyi @@ -20,6 +20,8 @@ from . import filters as filters from . import converters as converters from . import validators as validators +from ._version import VersionInfo + _T = TypeVar("_T") _C = TypeVar("_C", bound=type) diff --git a/src/attr/_version.pyi b/src/attr/_version.pyi new file mode 100644 index 000000000..36d7cf0b9 --- /dev/null +++ b/src/attr/_version.pyi @@ -0,0 +1,5 @@ +class VersionInfo: + year: int + minor: int + micro: int + releaselevel: str diff --git a/tox.ini b/tox.ini index 77ebe245a..96a472889 100644 --- a/tox.ini +++ b/tox.ini @@ -93,5 +93,5 @@ commands = towncrier --draft basepython = python3.7 deps = mypy commands = - mypy src/attr/__init__.pyi src/attr/converters.pyi src/attr/exceptions.pyi src/attr/filters.pyi src/attr/validators.pyi + mypy src/attr/__init__.pyi src/attr/_version.pyi src/attr/converters.pyi src/attr/exceptions.pyi src/attr/filters.pyi src/attr/validators.pyi mypy tests/typing_example.py From 346024aa3fb8005a12fea765d8fae777c25a6dbf Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Thu, 26 Sep 2019 07:38:04 +0200 Subject: [PATCH 6/9] Address David's feedback --- src/attr/__init__.pyi | 11 +++++++++++ src/attr/_version.pyi | 12 ++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/attr/__init__.pyi b/src/attr/__init__.pyi index 1e7bf26a1..d19a05546 100644 --- a/src/attr/__init__.pyi +++ b/src/attr/__init__.pyi @@ -22,6 +22,17 @@ from . import validators as validators from ._version import VersionInfo +__version__: str +__version_info__: VersionInfo +__title__: str +__description__: str +__url__: str +__uri__: str +__author__: str +__email__: str +__license__: str +__copyright__: str + _T = TypeVar("_T") _C = TypeVar("_C", bound=type) diff --git a/src/attr/_version.pyi b/src/attr/_version.pyi index 36d7cf0b9..45ced0863 100644 --- a/src/attr/_version.pyi +++ b/src/attr/_version.pyi @@ -1,5 +1,9 @@ class VersionInfo: - year: int - minor: int - micro: int - releaselevel: str + @property + def year(self) -> int: ... + @property + def minor(self) -> int: ... + @property + def micro(self) -> int: ... + @property + def releaselevel(self) -> str: ... From 568aa33d56ab2c8e8b3408decc159995bea3869c Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Tue, 1 Oct 2019 15:58:57 +0200 Subject: [PATCH 7/9] Handle PY2 better in comparability test --- tests/test_version.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/test_version.py b/tests/test_version.py index d35bc7a69..6b33770e1 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -18,6 +18,9 @@ def test_from_string_no_releaselevel(self, vi): """ assert vi == VersionInfo._from_version_string("19.2.0") + @pytest.mark.skipif( + PY2, reason="Python 2 is too YOLO to care about comparability." + ) @pytest.mark.parametrize("other", [(), (19, 2, 0, "final", "garbage")]) def test_wrong_len(self, vi, other): """ @@ -25,9 +28,8 @@ def test_wrong_len(self, vi, other): """ assert vi != other - if not PY2: - with pytest.raises(TypeError): - vi < other + with pytest.raises(TypeError): + vi < other @pytest.mark.parametrize("other", [[19, 2, 0, "final"]]) def test_wrong_type(self, vi, other): From 735b3bef489d105d86536e4fab2c916a256bd506 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Tue, 1 Oct 2019 16:00:33 +0200 Subject: [PATCH 8/9] drop the ing --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index ebe2a8138..7e965b9f9 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -508,7 +508,7 @@ Deprecated APIs .. _version-info: -To help you writing backward compatible code that doesn't throw warnings on modern releases, the ``attr`` module has an ``__version_info__`` attribute as of version 19.2.0. +To help you write backward compatible code that doesn't throw warnings on modern releases, the ``attr`` module has an ``__version_info__`` attribute as of version 19.2.0. It behaves similarly to `sys.version_info` and is an instance of `VersionInfo`: .. autoclass:: VersionInfo From 528323040f429e725ce35250af1c0ff51b632dac Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Tue, 1 Oct 2019 16:21:36 +0200 Subject: [PATCH 9/9] Prepare 19.2.0 --- CHANGELOG.rst | 71 ++++++++++++++++++++++++++++++--- changelog.d/504.breaking.rst | 2 - changelog.d/517.change.rst | 1 - changelog.d/522.change.rst | 1 - changelog.d/523.change.rst | 1 - changelog.d/533.change.rst | 1 - changelog.d/536.change.rst | 2 - changelog.d/543.change.rst | 1 - changelog.d/552.change.rst | 1 - changelog.d/556.change.rst | 1 - changelog.d/559.change.rst | 1 - changelog.d/560.change.rst | 2 - changelog.d/563.change.rst | 1 - changelog.d/568.change.rst | 2 - changelog.d/570.breaking.rst | 3 -- changelog.d/574.deprecation.rst | 11 ----- changelog.d/580.change.rst | 2 - docs/extending.rst | 2 +- src/attr/__init__.py | 2 +- 19 files changed, 67 insertions(+), 41 deletions(-) delete mode 100644 changelog.d/504.breaking.rst delete mode 100644 changelog.d/517.change.rst delete mode 100644 changelog.d/522.change.rst delete mode 100644 changelog.d/523.change.rst delete mode 100644 changelog.d/533.change.rst delete mode 100644 changelog.d/536.change.rst delete mode 100644 changelog.d/543.change.rst delete mode 100644 changelog.d/552.change.rst delete mode 100644 changelog.d/556.change.rst delete mode 100644 changelog.d/559.change.rst delete mode 100644 changelog.d/560.change.rst delete mode 100644 changelog.d/563.change.rst delete mode 100644 changelog.d/568.change.rst delete mode 100644 changelog.d/570.breaking.rst delete mode 100644 changelog.d/574.deprecation.rst delete mode 100644 changelog.d/580.change.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f60e83eb7..4f86e49ad 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,16 +4,75 @@ Changelog Versions follow `CalVer `_ with a strict backwards compatibility policy. The third digit is only for regressions. -Changes for the upcoming release can be found in the `"changelog.d" directory `_ in our repository. +.. towncrier release notes start + +19.2.0 (2019-10-01) +------------------- -.. - Do *NOT* add changelog entries here! +Backward-incompatible Changes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - This changelog is managed by towncrier and is compiled at release time. +- Removed deprecated ``Attribute`` attribute ``convert`` per scheduled removal on 2019/1. + This planned deprecation is tracked in issue `#307 `_. + `#504 `_ +- ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` do not consider subclasses comparable anymore. - See https://www.attrs.org/en/latest/contributing.html#changelog for details. + This has been deprecated since 18.2.0 and was raising a ``DeprecationWarning`` for over a year. + `#570 `_ + + +Deprecations +^^^^^^^^^^^^ + +- The ``cmp`` argument to ``attr.s()`` and ``attr.ib()`` is now deprecated. + + Please use ``eq`` to add equality methods (``__eq__`` and ``__ne__``) and ``order`` to add ordering methods (``__lt__``, ``__le__``, ``__gt__``, and ``__ge__``) instead – just like with `dataclasses `_. + + Both are effectively ``True`` by default but it's enough to set ``eq=False`` to disable both at once. + Passing ``eq=False, order=True`` explicitly will raise a ``ValueError`` though. + + Since this is arguably a deeper backward-compatibility break, it will have an extended deprecation period until 2021-06-01. + After that day, the ``cmp`` argument will be removed. + + ``attr.Attribute`` also isn't orderable anymore. + `#574 `_ + + +Changes +^^^^^^^ + +- Updated ``attr.validators.__all__`` to include new validators added in `#425 `_. + `#517 `_ +- Slotted classes now use a pure Python mechanism to rewrite the ``__class__`` cell when rebuilding the class, so ``super()`` works even on environments where ``ctypes`` is not installed. + `#522 `_ +- When collecting attributes using ``@attr.s(auto_attribs=True)``, attributes with a default of ``None`` are now deleted too. + `#523 `_, + `#556 `_ +- Fixed ``attr.validators.deep_iterable()`` and ``attr.validators.deep_mapping()`` type stubs. + `#533 `_ +- ``attr.validators.is_callable()`` validator now raises an exception ``attr.exceptions.NotCallableError``, a subclass of ``TypeError``, informing the received value. + `#536 `_. + `#536 `_ +- ``@attr.s(auto_exc=True)`` now generates classes that are hashable by ID, as the documentation always claimed it would. + `#543 `_, + `#563 `_ +- Added ``attr.validators.matches_re()`` that checks string attributes whether they match a regular expression. + `#552 `_ +- Keyword-only attributes (``kw_only=True``) and attributes that are excluded from the ``attrs``'s ``__init__`` (``init=False``) now can appear before mandatory attributes. + `#559 `_ +- The fake filename for generated methods is now more stable. + It won't change when you restart the process. + `#560 `_ +- The value passed to ``@attr.ib(repr=…)`` can now be either a boolean (as before) or a callable. + That callable must return a string and is then used for formatting the attribute by the generated ``__repr__()`` method. + `#568 `_ +- Added ``attr.__version_info__`` that can be used to reliably check the version of ``attrs`` and write forward- and backward-compatible code. + Please check out the `section on deprecated APIs `_ on how to use it. + `#580 `_ + + +---- -.. towncrier release notes start 19.1.0 (2019-03-03) ------------------- diff --git a/changelog.d/504.breaking.rst b/changelog.d/504.breaking.rst deleted file mode 100644 index d68c4a7d4..000000000 --- a/changelog.d/504.breaking.rst +++ /dev/null @@ -1,2 +0,0 @@ -Removed deprecated ``Attribute`` attribute ``convert`` per scheduled removal on 2019/1. -This planned deprecation is tracked in issue `#307 `_. diff --git a/changelog.d/517.change.rst b/changelog.d/517.change.rst deleted file mode 100644 index 50d3e33dd..000000000 --- a/changelog.d/517.change.rst +++ /dev/null @@ -1 +0,0 @@ -Updated ``attr.validators.__all__`` to include new validators added in `#425 `_. diff --git a/changelog.d/522.change.rst b/changelog.d/522.change.rst deleted file mode 100644 index 4b827e8fa..000000000 --- a/changelog.d/522.change.rst +++ /dev/null @@ -1 +0,0 @@ -Slotted classes now use a pure Python mechanism to rewrite the ``__class__`` cell when rebuilding the class, so ``super()`` works even on environments where ``ctypes`` is not installed. diff --git a/changelog.d/523.change.rst b/changelog.d/523.change.rst deleted file mode 100644 index 86bf8cdac..000000000 --- a/changelog.d/523.change.rst +++ /dev/null @@ -1 +0,0 @@ -When collecting attributes using ``@attr.s(auto_attribs=True)``, attributes with a default of ``None`` are now deleted too. diff --git a/changelog.d/533.change.rst b/changelog.d/533.change.rst deleted file mode 100644 index 3365ed00a..000000000 --- a/changelog.d/533.change.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed ``attr.validators.deep_iterable()`` and ``attr.validators.deep_mapping()`` type stubs. diff --git a/changelog.d/536.change.rst b/changelog.d/536.change.rst deleted file mode 100644 index 71f96a3f0..000000000 --- a/changelog.d/536.change.rst +++ /dev/null @@ -1,2 +0,0 @@ -``attr.validators.is_callable()`` validator now raises an exception ``attr.exceptions.NotCallableError``, a subclass of ``TypeError``, informing the received value. -`#536 `_. diff --git a/changelog.d/543.change.rst b/changelog.d/543.change.rst deleted file mode 100644 index 906275efa..000000000 --- a/changelog.d/543.change.rst +++ /dev/null @@ -1 +0,0 @@ -``@attr.s(auto_exc=True)`` now generates classes that are hashable by ID, as the documentation always claimed it would. diff --git a/changelog.d/552.change.rst b/changelog.d/552.change.rst deleted file mode 100644 index e33c5dcd9..000000000 --- a/changelog.d/552.change.rst +++ /dev/null @@ -1 +0,0 @@ -Added ``attr.validators.matches_re()`` that checks string attributes whether they match a regular expression. diff --git a/changelog.d/556.change.rst b/changelog.d/556.change.rst deleted file mode 100644 index 86bf8cdac..000000000 --- a/changelog.d/556.change.rst +++ /dev/null @@ -1 +0,0 @@ -When collecting attributes using ``@attr.s(auto_attribs=True)``, attributes with a default of ``None`` are now deleted too. diff --git a/changelog.d/559.change.rst b/changelog.d/559.change.rst deleted file mode 100644 index 66498c387..000000000 --- a/changelog.d/559.change.rst +++ /dev/null @@ -1 +0,0 @@ -Keyword-only attributes (``kw_only=True``) and attributes that are excluded from the ``attrs``'s ``__init__`` (``init=False``) now can appear before mandatory attributes. diff --git a/changelog.d/560.change.rst b/changelog.d/560.change.rst deleted file mode 100644 index 2183305d9..000000000 --- a/changelog.d/560.change.rst +++ /dev/null @@ -1,2 +0,0 @@ -The fake filename for generated methods is now more stable. -It won't change when you restart the process. diff --git a/changelog.d/563.change.rst b/changelog.d/563.change.rst deleted file mode 100644 index 906275efa..000000000 --- a/changelog.d/563.change.rst +++ /dev/null @@ -1 +0,0 @@ -``@attr.s(auto_exc=True)`` now generates classes that are hashable by ID, as the documentation always claimed it would. diff --git a/changelog.d/568.change.rst b/changelog.d/568.change.rst deleted file mode 100644 index 320491019..000000000 --- a/changelog.d/568.change.rst +++ /dev/null @@ -1,2 +0,0 @@ -The value passed to ``@attr.ib(repr=…)`` can now be either a boolean (as before) or a callable. -That callable must return a string and is then used for formatting the attribute by the generated ``__repr__()`` method. diff --git a/changelog.d/570.breaking.rst b/changelog.d/570.breaking.rst deleted file mode 100644 index 21cc77997..000000000 --- a/changelog.d/570.breaking.rst +++ /dev/null @@ -1,3 +0,0 @@ -``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` do not consider subclasses comparable anymore. - -This has been deprecated since 18.2.0 and was raising a ``DeprecationWarning`` for over a year. diff --git a/changelog.d/574.deprecation.rst b/changelog.d/574.deprecation.rst deleted file mode 100644 index 130fe4d93..000000000 --- a/changelog.d/574.deprecation.rst +++ /dev/null @@ -1,11 +0,0 @@ -The ``cmp`` argument to ``attr.s()`` and ``attr.ib()`` is now deprecated. - -Please use ``eq`` to add equality methods (``__eq__`` and ``__ne__``) and ``order`` to add ordering methods (``__lt__``, ``__le__``, ``__gt__``, and ``__ge__``) instead – just like with `dataclasses `_. - -Both are effectively ``True`` by default but it's enough to set ``eq=False`` to disable both at once. -Passing ``eq=False, order=True`` explicitly will raise a ``ValueError`` though. - -Since this is arguably a deeper backward-compatibility break, it will have an extended deprecation period until 2021-06-01. -After that day, the ``cmp`` argument will be removed. - -``attr.Attribute`` also isn't orderable anymore. diff --git a/changelog.d/580.change.rst b/changelog.d/580.change.rst deleted file mode 100644 index 74a993457..000000000 --- a/changelog.d/580.change.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added ``attr.__version_info__`` that can be used to reliably check the version of ``attrs`` and write forward- and backward-compatible code. -Please check out the `section on deprecated APIs `_ on how to use it. diff --git a/docs/extending.rst b/docs/extending.rst index 4ee201ed3..c92e1fd9e 100644 --- a/docs/extending.rst +++ b/docs/extending.rst @@ -42,7 +42,7 @@ Wrapping the Decorator A more elegant way can be to wrap ``attrs`` altogether and build a class `DSL `_ on top of it. -An example for that is the package `environ_config `_ that uses ``attrs`` under the hood to define environment-based configurations declaratively without exposing ``attrs`` APIs at all. +An example for that is the package `environ-config `_ that uses ``attrs`` under the hood to define environment-based configurations declaratively without exposing ``attrs`` APIs at all. Types diff --git a/src/attr/__init__.py b/src/attr/__init__.py index c28f0568b..66ce10920 100644 --- a/src/attr/__init__.py +++ b/src/attr/__init__.py @@ -19,7 +19,7 @@ from ._version import VersionInfo -__version__ = "19.2.0.dev0" +__version__ = "19.2.0" __version_info__ = VersionInfo._from_version_string(__version__) __title__ = "attrs"