Skip to content

Commit 57f955f

Browse files
[3.12] gh-120449: fix test_pyclbr introspection for mangled names (GH-120450) (GH-120701)
gh-120449: fix ``test_pyclbr`` introspection for mangled names (GH-120450) (cherry picked from commit d8cd0fa) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent 70d71fb commit 57f955f

File tree

2 files changed

+75
-17
lines changed

2 files changed

+75
-17
lines changed

Lib/test/pyclbr_input.py

+60-8
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,19 @@ class B (object):
1212
def bm(self): pass
1313

1414
class C (B):
15-
foo = Other().foo
16-
om = Other.om
17-
1815
d = 10
1916

20-
# XXX: This causes test_pyclbr.py to fail, but only because the
21-
# introspection-based is_method() code in the test can't
22-
# distinguish between this and a genuine method function like m().
23-
# The pyclbr.py module gets this right as it parses the text.
17+
# This one is correctly considered by both test_pyclbr.py and pyclbr.py
18+
# as a non-method of C.
19+
foo = Other().foo
20+
21+
# This causes test_pyclbr.py to fail, but only because the
22+
# introspection-based is_method() code in the test can't
23+
# distinguish between this and a genuine method function like m().
2424
#
25-
#f = f
25+
# The pyclbr.py module gets this right as it parses the text.
26+
om = Other.om
27+
f = f
2628

2729
def m(self): pass
2830

@@ -31,3 +33,53 @@ def sm(self): pass
3133

3234
@classmethod
3335
def cm(self): pass
36+
37+
# Check that mangling is correctly handled
38+
39+
class a:
40+
def a(self): pass
41+
def _(self): pass
42+
def _a(self): pass
43+
def __(self): pass
44+
def ___(self): pass
45+
def __a(self): pass
46+
47+
class _:
48+
def a(self): pass
49+
def _(self): pass
50+
def _a(self): pass
51+
def __(self): pass
52+
def ___(self): pass
53+
def __a(self): pass
54+
55+
class __:
56+
def a(self): pass
57+
def _(self): pass
58+
def _a(self): pass
59+
def __(self): pass
60+
def ___(self): pass
61+
def __a(self): pass
62+
63+
class ___:
64+
def a(self): pass
65+
def _(self): pass
66+
def _a(self): pass
67+
def __(self): pass
68+
def ___(self): pass
69+
def __a(self): pass
70+
71+
class _a:
72+
def a(self): pass
73+
def _(self): pass
74+
def _a(self): pass
75+
def __(self): pass
76+
def ___(self): pass
77+
def __a(self): pass
78+
79+
class __a:
80+
def a(self): pass
81+
def _(self): pass
82+
def _a(self): pass
83+
def __(self): pass
84+
def ___(self): pass
85+
def __a(self): pass

Lib/test/test_pyclbr.py

+15-9
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ def ismethod(oclass, obj, name):
7878

7979
objname = obj.__name__
8080
if objname.startswith("__") and not objname.endswith("__"):
81-
objname = "_%s%s" % (oclass.__name__, objname)
81+
if stripped_typename := oclass.__name__.lstrip('_'):
82+
objname = f"_{stripped_typename}{objname}"
8283
return objname == name
8384

8485
# Make sure the toplevel functions and classes are the same.
@@ -111,12 +112,16 @@ def ismethod(oclass, obj, name):
111112
for m in py_item.__dict__.keys():
112113
if ismethod(py_item, getattr(py_item, m), m):
113114
actualMethods.append(m)
114-
foundMethods = []
115-
for m in value.methods.keys():
116-
if m[:2] == '__' and m[-2:] != '__':
117-
foundMethods.append('_'+name+m)
118-
else:
119-
foundMethods.append(m)
115+
116+
if stripped_typename := name.lstrip('_'):
117+
foundMethods = []
118+
for m in value.methods.keys():
119+
if m.startswith('__') and not m.endswith('__'):
120+
foundMethods.append(f"_{stripped_typename}{m}")
121+
else:
122+
foundMethods.append(m)
123+
else:
124+
foundMethods = list(value.methods.keys())
120125

121126
try:
122127
self.assertListEq(foundMethods, actualMethods, ignore)
@@ -150,8 +155,9 @@ def test_easy(self):
150155
"DocTestCase", '_DocTestSuite'))
151156
self.checkModule('difflib', ignore=("Match",))
152157

153-
def test_decorators(self):
154-
self.checkModule('test.pyclbr_input', ignore=['om'])
158+
def test_cases(self):
159+
# see test.pyclbr_input for the rationale behind the ignored symbols
160+
self.checkModule('test.pyclbr_input', ignore=['om', 'f'])
155161

156162
def test_nested(self):
157163
mb = pyclbr

0 commit comments

Comments
 (0)