-
-
Notifications
You must be signed in to change notification settings - Fork 359
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add attr.__version_info__ This allows users to check for features and avoid deprecation warnings without breaking backward compatibility. * Add newsfragment * Stay ASCII * Typo * Add stubs for _version.py * Address David's feedback * Handle PY2 better in comparability test * drop the ing
- Loading branch information
Showing
8 changed files
with
188 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <http://www.attrs.org/en/stable/api.html#deprecated-apis>`_ on how to use it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
class VersionInfo: | ||
@property | ||
def year(self) -> int: ... | ||
@property | ||
def minor(self) -> int: ... | ||
@property | ||
def micro(self) -> int: ... | ||
@property | ||
def releaselevel(self) -> str: ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
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.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): | ||
""" | ||
Comparing with a tuple that has the wrong length raises an error. | ||
""" | ||
assert vi != other | ||
|
||
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") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters