11from __future__ import annotations
22
3- import importlib .metadata
43import re
54import warnings
6- from functools import wraps
75
86import pytest
97
108from mcstatus ._utils .deprecation import _get_project_version , deprecated , deprecation_warn
9+ from tests .helpers import patch_project_version
1110
1211LIB_NAME = "mcstatus"
1312
1413
15- def _patch_project_version (monkeypatch : pytest .MonkeyPatch , version : str | None ):
16- """Patch the project version reported by ``importlib.metadata.version``.
17-
18- This is used to simulate different project versions for testing purposes.
19- If ``version`` is ``None``, a :exc:`PackageNotFoundError` will be raised
20- when trying to get the project version.
21- """
22- orig_version_func = importlib .metadata .version
23-
24- @wraps (orig_version_func )
25- def patched_version_func (distribution_name : str ) -> str :
26- if distribution_name == LIB_NAME :
27- if version is None :
28- raise importlib .metadata .PackageNotFoundError
29- return version
30- return orig_version_func (distribution_name )
31-
32- _get_project_version .cache_clear ()
33- monkeypatch .setattr (importlib .metadata , "version" , patched_version_func )
34-
35-
36- def test_invalid_lib_version (monkeypatch : pytest .MonkeyPatch ):
37- _patch_project_version (monkeypatch , "foo bar" )
38-
39- with pytest .warns (match = f"^Failed to parse { LIB_NAME } project version \\ (foo bar\\ ), assuming v0\\ .0\\ .0$" ):
14+ def test_invalid_lib_version ():
15+ with (
16+ patch_project_version ("foo bar" ),
17+ pytest .warns (match = f"^Failed to parse { LIB_NAME } project version \\ (foo bar\\ ), assuming v0\\ .0\\ .0$" ),
18+ ):
4019 _get_project_version ()
4120
4221
43- def test_epoch_in_lib_version (monkeypatch : pytest .MonkeyPatch ):
44- _patch_project_version (monkeypatch , "2!1.2.3" )
45-
46- with pytest .warns (match = f"^Failed to parse { LIB_NAME } project version, assuming v0\\ .0\\ .0$" ):
22+ def test_epoch_in_lib_version ():
23+ with (
24+ patch_project_version ("2!1.2.3" ),
25+ pytest .warns (
26+ match = f"^Failed to parse { LIB_NAME } project version, assuming v0\\ .0\\ .0$" ,
27+ ),
28+ ):
4729 _get_project_version ()
4830
4931
5032@pytest .mark .parametrize ("removal_version" , ["0.9.0" , (0 , 9 , 0 )])
51- def test_deprecation_warn_produces_error (monkeypatch : pytest . MonkeyPatch , removal_version : str | tuple [int , int , int ]):
33+ def test_deprecation_warn_produces_error (removal_version : str | tuple [int , int , int ]):
5234 """Test deprecation_warn with older removal_version than current version produces exception."""
53- _patch_project_version (monkeypatch , "1.0.0" )
54-
55- with pytest .raises (DeprecationWarning , match = r"^test is passed its removal version \(0\.9\.0\)\.$" ):
35+ with (
36+ patch_project_version ("1.0.0" ),
37+ pytest .raises (
38+ DeprecationWarning ,
39+ match = r"^test is passed its removal version \(0\.9\.0\)\.$" ,
40+ ),
41+ ):
5642 deprecation_warn (obj_name = "test" , removal_version = removal_version )
5743
5844
5945@pytest .mark .parametrize ("removal_version" , ["1.0.1" , (1 , 0 , 1 )])
60- def test_deprecation_warn_produces_warning (monkeypatch : pytest . MonkeyPatch , removal_version : str | tuple [int , int , int ]):
46+ def test_deprecation_warn_produces_warning (removal_version : str | tuple [int , int , int ]):
6147 """Test deprecation_warn with newer removal_version than current version produces warning."""
62- _patch_project_version (monkeypatch , "1.0.0" )
63-
64- with pytest .deprecated_call (match = r"^test is deprecated and scheduled for removal in 1\.0\.1\.$" ):
48+ with (
49+ patch_project_version ("1.0.0" ),
50+ pytest .deprecated_call (
51+ match = r"^test is deprecated and scheduled for removal in 1\.0\.1\.$" ,
52+ ),
53+ ):
6554 deprecation_warn (obj_name = "test" , removal_version = removal_version )
6655
6756
68- def test_deprecation_invalid_removal_version (monkeypatch : pytest . MonkeyPatch ):
57+ def test_deprecation_invalid_removal_version ():
6958 """Test deprecation_warn with invalid removal_version."""
70- _patch_project_version (monkeypatch , "1.0.0" )
71-
7259 pattern = re .escape (r"(\d+)\.(\d+)\.(\d+)" )
73- with pytest .raises (ValueError , match = f"^removal_version must follow regex pattern of: { pattern } $" ):
60+ with (
61+ patch_project_version ("1.0.0" ),
62+ pytest .raises (
63+ ValueError ,
64+ match = f"^removal_version must follow regex pattern of: { pattern } $" ,
65+ ),
66+ ):
7467 deprecation_warn (obj_name = "test" , removal_version = "foo!" )
7568
7669
77- def test_deprecation_warn_unknown_version (monkeypatch : pytest . MonkeyPatch ):
70+ def test_deprecation_warn_unknown_version ():
7871 """Test deprecation_warn with unknown project version.
7972
8073 This could occur if the project wasn't installed as a package. (e.g. when running directly from
8174 source, like via a git submodule.)
8275 """
83- _patch_project_version (monkeypatch , None )
84-
8576 with (
77+ patch_project_version (None ),
8678 pytest .warns (match = f"Failed to get { LIB_NAME } project version" , expected_warning = RuntimeWarning ),
8779 pytest .deprecated_call (match = r"^test is deprecated and scheduled for removal in 1\.0\.0\.$" ),
8880 ):
8981 deprecation_warn (obj_name = "test" , removal_version = "1.0.0" )
9082
9183
92- def test_deprecation_decorator_warn (monkeypatch : pytest . MonkeyPatch ):
84+ def test_deprecation_decorator_warn ():
9385 """Check deprecated decorator triggers a deprecation warning."""
94- _patch_project_version ( monkeypatch , "1.0.0" )
86+ with patch_project_version ( "1.0.0" ):
9587
96- @deprecated (display_name = "func" , removal_version = "1.0.1" )
97- def func (x : object ) -> object :
98- return x
88+ @deprecated (display_name = "func" , removal_version = "1.0.1" )
89+ def func (x : object ) -> object :
90+ return x
9991
100- with pytest .deprecated_call (match = r"^func is deprecated and scheduled for removal in 1\.0\.1\.$" ):
101- assert func (5 ) == 5
92+ with pytest .deprecated_call (match = r"^func is deprecated and scheduled for removal in 1\.0\.1\.$" ):
93+ assert func (5 ) == 5
10294
10395
104- def test_deprecation_decorator_inferred_name (monkeypatch : pytest . MonkeyPatch ):
96+ def test_deprecation_decorator_inferred_name ():
10597 """Check deprecated decorator properly infers qualified name of decorated object shown in warning."""
106- _patch_project_version ( monkeypatch , "1.0.0" )
98+ with patch_project_version ( "1.0.0" ):
10799
108- @deprecated (removal_version = "1.0.1" )
109- def func (x : object ) -> object :
110- return x
100+ @deprecated (removal_version = "1.0.1" )
101+ def func (x : object ) -> object :
102+ return x
111103
112- qualname = r"test_deprecation_decorator_inferred_name\.<locals>\.func"
113- with pytest .deprecated_call (match = rf"^{ qualname } is deprecated and scheduled for removal in 1\.0\.1\.$" ):
114- assert func (5 ) == 5
104+ qualname = r"test_deprecation_decorator_inferred_name\.<locals>\.func"
105+ with pytest .deprecated_call (match = rf"^{ qualname } is deprecated and scheduled for removal in 1\.0\.1\.$" ):
106+ assert func (5 ) == 5
115107
116108
117109@pytest .mark .parametrize (
@@ -130,11 +122,9 @@ def func(x: object) -> object:
130122 ("1.2.3rc1.post2.dev3+loc.1" , (1 , 2 , 3 )),
131123 ],
132124)
133- def test_project_version_non_normalized_parsing (monkeypatch : pytest . MonkeyPatch , version : str , expected : tuple [int , int , int ]):
125+ def test_project_version_non_normalized_parsing (version : str , expected : tuple [int , int , int ]):
134126 """Ensure PEP440 release versions get parsed out properly, with non-release components are ignored."""
135- _patch_project_version (monkeypatch , version )
136-
137- with warnings .catch_warnings ():
127+ with patch_project_version (version ), warnings .catch_warnings ():
138128 warnings .simplefilter ("error" ) # raise warnings as errors (test there are no warnings)
139129
140130 assert _get_project_version () == expected
@@ -157,13 +147,10 @@ def test_project_version_non_normalized_parsing(monkeypatch: pytest.MonkeyPatch,
157147 ids = ["1.2" , "1.2.3.4" ],
158148)
159149def test_project_version_normalizes_release_components (
160- monkeypatch : pytest .MonkeyPatch ,
161150 version : str ,
162151 expected : tuple [int , int , int ],
163152 warning : str ,
164153):
165154 """Ensure release segments normalize to a 3-component version and warn."""
166- _patch_project_version (monkeypatch , version )
167-
168- with pytest .warns (RuntimeWarning , match = rf"^{ re .escape (warning )} $" ):
155+ with patch_project_version (version ), pytest .warns (RuntimeWarning , match = rf"^{ re .escape (warning )} $" ):
169156 assert _get_project_version () == expected
0 commit comments