Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit45c128b

Browse files
committed
Finish reorganizing; fix assertion for duplicated messages
To support the changes, this adds typing-extensions as a testdependency, since we are now importing from it in a test module.But this should probably be required and used conditionally basedon whether the Python version has assert_type in its typing module.
1 parent9d58e6d commit45c128b

File tree

2 files changed

+50
-49
lines changed

2 files changed

+50
-49
lines changed

‎test-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ pytest-cov
88
pytest-instafail
99
pytest-mock
1010
pytest-sugar
11+
typing-extensions

‎test/deprecation/test_attributes.py

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,61 +4,72 @@
44
checks static typing of the code under test. (Running pytest checks dynamic behavior.)
55
"""
66

7-
importimportlib
7+
fromitertoolsimportgroupby
88
fromtypingimportType
99

1010
importpytest
11+
fromtyping_extensionsimportassert_type
1112

1213
importgit
1314

1415

15-
deftest_cannot_get_undefined()->None:
16+
deftest_cannot_access_undefined()->None:
17+
"""Accessing a bogus attribute in git remains both a dynamic and static error."""
1618
withpytest.raises(AttributeError):
1719
git.foo# type: ignore[attr-defined]
1820

1921

2022
deftest_cannot_import_undefined()->None:
23+
"""Importing a bogus attribute from git remains both a dynamic and static error."""
2124
withpytest.raises(ImportError):
2225
fromgitimportfoo# type: ignore[attr-defined] # noqa: F401
2326

2427

25-
deftest_util_alias_members_resolve()->None:
26-
"""git.index.util members can be accessed via git.util, and mypy recognizes it."""
27-
gu_tfs=git.util.TemporaryFileSwap
28-
fromgit.index.utilimportTemporaryFileSwap
28+
deftest_util_alias_access()->None:
29+
"""Accessing util in git works, warns, and mypy verifies it and its attributes."""
30+
# The attribute access should succeed.
31+
withpytest.deprecated_call()asctx:
32+
util=git.util
2933

30-
defaccepts_tfs_type(t:Type[TemporaryFileSwap])->None:
31-
pass
34+
# There should be exactly one warning and it should have our util-specific message.
35+
(message,)= [str(entry.message)forentryinctx]
36+
assert"git.util"inmessage
37+
assert"git.index.util"inmessage
38+
assert"should not be relied on"inmessage
3239

33-
defrejects_tfs_type(t:Type[git.Git])->None:
34-
pass
40+
# We check access through the util alias to the TemporaryFileSwap member, since it
41+
# is slightly simpler to validate and reason about than the other public members,
42+
# which are functions (specifically, higher-order functions for use as decorators).
43+
fromgit.index.utilimportTemporaryFileSwap
3544

36-
# TODO: When typing_extensions is made a test dependency, use assert_type for this.
37-
accepts_tfs_type(gu_tfs)
38-
rejects_tfs_type(gu_tfs)# type: ignore[arg-type]
45+
assert_type(util.TemporaryFileSwap,Type[TemporaryFileSwap])
3946

40-
assertgu_tfsisTemporaryFileSwap
47+
# This comes after the static assertion, just in case it would affect the inference.
48+
assertutil.TemporaryFileSwapisTemporaryFileSwap
4149

4250

43-
deftest_util_alias_access_warns()->None:
51+
deftest_util_alias_import()->None:
52+
"""Importing util from git works, warns, and mypy verifies it and its attributes."""
53+
# The import should succeed.
4454
withpytest.deprecated_call()asctx:
45-
git.util
55+
fromgitimportutil
4656

47-
assertlen(ctx)==1
48-
message=str(ctx[0].message)
57+
# There may be multiple warnings. In CPython there will be currently always be
58+
# exactly two, possibly due to the equivalent of calling hasattr to do a pre-check
59+
# prior to retrieving the attribute for actual use. However, all warnings should
60+
# have the same message, and it should be our util-specific message.
61+
(message,)= {str(entry.message)forentryinctx}
4962
assert"git.util"inmessage
5063
assert"git.index.util"inmessage
5164
assert"should not be relied on"inmessage
5265

66+
# As above, we check access through the util alias to the TemporaryFileSwap member.
67+
fromgit.index.utilimportTemporaryFileSwap
5368

54-
deftest_util_alias_import_warns()->None:
55-
withpytest.deprecated_call()asctx:
56-
fromgitimportutil# noqa: F401
69+
assert_type(util.TemporaryFileSwap,Type[TemporaryFileSwap])
5770

58-
message=str(ctx[0].message)
59-
assert"git.util"inmessage
60-
assert"git.index.util"inmessage
61-
assert"should not be relied on"inmessage
71+
# This comes after the static assertion, just in case it would affect the inference.
72+
assertutil.TemporaryFileSwapisTemporaryFileSwap
6273

6374

6475
# Split out util and have all its tests be separate, above.
@@ -71,12 +82,11 @@ def test_util_alias_import_warns() -> None:
7182
git.index.base,
7283
git.index.fun,
7384
git.index.typ,
74-
git.index.util,
7585
)
7686

7787

78-
deftest_private_module_alias_access_on_git_module()->None:
79-
"""Privatealias access works, warns,and except for utilis a mypy error."""
88+
deftest_private_module_alias_access()->None:
89+
"""Non-util privatealias access works, warns,butis a deliberate mypy error."""
8090
withpytest.deprecated_call()asctx:
8191
assert (
8292
git.head,# type: ignore[attr-defined]
@@ -87,21 +97,16 @@ def test_private_module_alias_access_on_git_module() -> None:
8797
git.base,# type: ignore[attr-defined]
8898
git.fun,# type: ignore[attr-defined]
8999
git.typ,# type: ignore[attr-defined]
90-
git.util,
91100
)==_MODULE_ALIAS_TARGETS
92101

102+
# Each should have warned exactly once, and note what to use instead.
93103
messages= [str(w.message)forwinctx]
94-
fortarget,messageinzip(_MODULE_ALIAS_TARGETS[:-1],messages[:-1],strict=True):
104+
fortarget,messageinzip(_MODULE_ALIAS_TARGETS,messages,strict=True):
95105
assertmessage.endswith(f"Use{target.__name__} instead.")
96106

97-
util_message=messages[-1]
98-
assert"git.util"inutil_message
99-
assert"git.index.util"inutil_message
100-
assert"should not be relied on"inutil_message
101107

102-
103-
deftest_private_module_alias_import_from_git_module()->None:
104-
"""Private alias import works, warns, and except for util is a mypy error."""
108+
deftest_private_module_alias_import()->None:
109+
"""Non-util private alias access works, warns, but is a deliberate mypy error."""
105110
withpytest.deprecated_call()asctx:
106111
fromgitimporthead# type: ignore[attr-defined]
107112
fromgitimportlog# type: ignore[attr-defined]
@@ -111,7 +116,6 @@ def test_private_module_alias_import_from_git_module() -> None:
111116
fromgitimportbase# type: ignore[attr-defined]
112117
fromgitimportfun# type: ignore[attr-defined]
113118
fromgitimporttyp# type: ignore[attr-defined]
114-
fromgitimportutil
115119

116120
assert (
117121
head,
@@ -122,17 +126,13 @@ def test_private_module_alias_import_from_git_module() -> None:
122126
base,
123127
fun,
124128
typ,
125-
util,
126129
)==_MODULE_ALIAS_TARGETS
127130

128-
# FIXME: This fails because, with imports, multiple consecutive accesses may occur.
129-
# In practice, with CPython, it is always exactly two accesses, the first from the
130-
# equivalent of a hasattr, and the second to fetch the attribute intentionally.
131-
messages= [str(w.message)forwinctx]
132-
fortarget,messageinzip(_MODULE_ALIAS_TARGETS[:-1],messages[:-1],strict=True):
131+
# Each import may warn multiple times. In CPython there will be currently always be
132+
# exactly two warnings per import, possibly due to the equivalent of calling hasattr
133+
# to do a pre-check prior to retrieving the attribute for actual use. However, for
134+
# each import, all messages should be the same and should note what to use instead.
135+
messages_with_duplicates= [str(w.message)forwinctx]
136+
messages= [messageformessage,_ingroupby(messages_with_duplicates)]
137+
fortarget,messageinzip(_MODULE_ALIAS_TARGETS,messages,strict=True):
133138
assertmessage.endswith(f"Use{target.__name__} instead.")
134-
135-
util_message=messages[-1]
136-
assert"git.util"inutil_message
137-
assert"git.index.util"inutil_message
138-
assert"should not be relied on"inutil_message

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp