Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2d81709

Browse filesBrowse files
committed
Add __version_info__ as a tuple-based version identifier
This is a named tuple modelled after sys.version_info.
1 parent 0e16de7 commit 2d81709
Copy full SHA for 2d81709

File tree

Expand file treeCollapse file tree

3 files changed

+76
-16
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+76
-16
lines changed
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Version information
2+
-------------------
3+
We switched to the `release-branch-semver`_ version theme. This only affects,
4+
the version information for development builds. Their version number now
5+
describes the targeted release, i.e. 3.5.0.dev820+g6768ef8c4c.d20210520
6+
is 820 commits after the previous release and is scheduled to be officially
7+
released as 3.5.0 later.
8+
9+
In addition to the string ``__version__``, there is now a namedtuple
10+
``__version_info__`` as well, which is modelled after `sys.version_info`_.
11+
Its primary use is safely comparing version information, e.g.
12+
``if __version_info__ >= (3, 4, 2)``.
13+
14+
.. _release-branch-semver: https://github.com/pypa/setuptools_scm#version-number-construction
15+
.. _sys.version_info: https://docs.python.org/3/library/sys.html#sys.version_info

‎lib/matplotlib/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/__init__.py
+51-16Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -129,25 +129,60 @@
129129
year = 2007
130130
}"""
131131

132+
# modelled after sys.version_info
133+
_VersionInfo = namedtuple('_VersionInfo',
134+
'major, minor, micro, releaselevel, serial')
132135

133-
def __getattr__(name):
134-
if name == "__version__":
136+
137+
def _parse_to_version_info(version_str):
138+
"""
139+
Parse a version string to a namedtuple analogous to sys.version_info.
140+
141+
See:
142+
https://packaging.pypa.io/en/latest/version.html#packaging.version.parse
143+
https://docs.python.org/3/library/sys.html#sys.version_info
144+
"""
145+
v = parse_version(version_str)
146+
if v.pre is None and v.post is None and v.dev is None:
147+
return _VersionInfo(v.major, v.minor, v.micro, 'final', 0)
148+
elif v.dev is not None:
149+
return _VersionInfo(v.major, v.minor, v.micro, 'alpha', v.dev)
150+
elif v.pre is not None:
151+
releaselevel = {
152+
'a': 'alpha',
153+
'b': 'beta',
154+
'rc': 'candidate'}.get(v.pre[0], 'alpha')
155+
return _VersionInfo(v.major, v.minor, v.micro, releaselevel, v.pre[1])
156+
else:
157+
# fallback for v.post: guess-next-dev scheme from setuptools_scm
158+
return _VersionInfo(v.major, v.minor, v.micro + 1, 'alpha', v.post)
159+
160+
161+
def _get_version():
162+
"""Return the version string used for __version__."""
163+
# Only shell out to a git subprocess if really needed, and not on a
164+
# shallow clone, such as those used by CI, as the latter would trigger
165+
# a warning from setuptools_scm.
166+
root = Path(__file__).resolve().parents[2]
167+
if (root / ".git").exists() and not (root / ".git/shallow").exists():
135168
import setuptools_scm
169+
return setuptools_scm.get_version(
170+
root=root,
171+
version_scheme="post-release",
172+
local_scheme="node-and-date",
173+
fallback_version=_version.version,
174+
)
175+
else: # Get the version from the _version.py setuptools_scm file.
176+
return _version.version
177+
178+
179+
def __getattr__(name):
180+
if name in ("__version__", "__version_info__"):
136181
global __version__ # cache it.
137-
# Only shell out to a git subprocess if really needed, and not on a
138-
# shallow clone, such as those used by CI, as the latter would trigger
139-
# a warning from setuptools_scm.
140-
root = Path(__file__).resolve().parents[2]
141-
if (root / ".git").exists() and not (root / ".git/shallow").exists():
142-
__version__ = setuptools_scm.get_version(
143-
root=root,
144-
version_scheme="post-release",
145-
local_scheme="node-and-date",
146-
fallback_version=_version.version,
147-
)
148-
else: # Get the version from the _version.py setuptools_scm file.
149-
__version__ = _version.version
150-
return __version__
182+
__version__ = _get_version()
183+
global __version__info__ # cache it.
184+
__version_info__ = _parse_to_version_info(__version__)
185+
return __version__ if name == "__version__" else __version_info__
151186
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
152187

153188

‎lib/matplotlib/tests/test_matplotlib.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_matplotlib.py
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@
77
import matplotlib
88

99

10+
@pytest.mark.parametrize('version_str, version_tuple', [
11+
('3.5.0', (3, 5, 0, 'final', 0)),
12+
('3.5.0rc2', (3, 5, 0, 'candidate', 2)),
13+
('3.5.0.dev820+g6768ef8c4c', (3, 5, 0, 'alpha', 820)),
14+
('3.5.0.post820+g6768ef8c4c', (3, 5, 1, 'alpha', 820)),
15+
])
16+
def test_parse_to_version_info(version_str, version_tuple):
17+
assert matplotlib._parse_to_version_info(version_str) == version_tuple
18+
19+
1020
@pytest.mark.skipif(
1121
os.name == "nt", reason="chmod() doesn't work as is on Windows")
1222
@pytest.mark.skipif(os.name != "nt" and os.geteuid() == 0,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.