[3.13] gh-120449: fix ``test_pyclbr`` introspection for mangled names (GH-120450) (GH-120700)

gh-120449: fix ``test_pyclbr`` introspection for mangled names (GH-120450)
(cherry picked from commit d8cd0fa4e3)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2024-06-19 09:20:09 +02:00 committed by GitHub
parent 39c3f11f25
commit d65e145f9d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 75 additions and 17 deletions

View File

@ -12,17 +12,19 @@ class B (object):
def bm(self): pass def bm(self): pass
class C (B): class C (B):
foo = Other().foo
om = Other.om
d = 10 d = 10
# XXX: This causes test_pyclbr.py to fail, but only because the # This one is correctly considered by both test_pyclbr.py and pyclbr.py
# introspection-based is_method() code in the test can't # as a non-method of C.
# distinguish between this and a genuine method function like m(). foo = Other().foo
# The pyclbr.py module gets this right as it parses the text.
# This causes test_pyclbr.py to fail, but only because the
# introspection-based is_method() code in the test can't
# distinguish between this and a genuine method function like m().
# #
#f = f # The pyclbr.py module gets this right as it parses the text.
om = Other.om
f = f
def m(self): pass def m(self): pass
@ -31,3 +33,53 @@ class C (B):
@classmethod @classmethod
def cm(self): pass def cm(self): pass
# Check that mangling is correctly handled
class a:
def a(self): pass
def _(self): pass
def _a(self): pass
def __(self): pass
def ___(self): pass
def __a(self): pass
class _:
def a(self): pass
def _(self): pass
def _a(self): pass
def __(self): pass
def ___(self): pass
def __a(self): pass
class __:
def a(self): pass
def _(self): pass
def _a(self): pass
def __(self): pass
def ___(self): pass
def __a(self): pass
class ___:
def a(self): pass
def _(self): pass
def _a(self): pass
def __(self): pass
def ___(self): pass
def __a(self): pass
class _a:
def a(self): pass
def _(self): pass
def _a(self): pass
def __(self): pass
def ___(self): pass
def __a(self): pass
class __a:
def a(self): pass
def _(self): pass
def _a(self): pass
def __(self): pass
def ___(self): pass
def __a(self): pass

View File

@ -78,7 +78,8 @@ class PyclbrTest(TestCase):
objname = obj.__name__ objname = obj.__name__
if objname.startswith("__") and not objname.endswith("__"): if objname.startswith("__") and not objname.endswith("__"):
objname = "_%s%s" % (oclass.__name__, objname) if stripped_typename := oclass.__name__.lstrip('_'):
objname = f"_{stripped_typename}{objname}"
return objname == name return objname == name
# Make sure the toplevel functions and classes are the same. # Make sure the toplevel functions and classes are the same.
@ -111,12 +112,16 @@ class PyclbrTest(TestCase):
for m in py_item.__dict__.keys(): for m in py_item.__dict__.keys():
if ismethod(py_item, getattr(py_item, m), m): if ismethod(py_item, getattr(py_item, m), m):
actualMethods.append(m) actualMethods.append(m)
foundMethods = []
for m in value.methods.keys(): if stripped_typename := name.lstrip('_'):
if m[:2] == '__' and m[-2:] != '__': foundMethods = []
foundMethods.append('_'+name+m) for m in value.methods.keys():
else: if m.startswith('__') and not m.endswith('__'):
foundMethods.append(m) foundMethods.append(f"_{stripped_typename}{m}")
else:
foundMethods.append(m)
else:
foundMethods = list(value.methods.keys())
try: try:
self.assertListEq(foundMethods, actualMethods, ignore) self.assertListEq(foundMethods, actualMethods, ignore)
@ -150,8 +155,9 @@ class PyclbrTest(TestCase):
"DocTestCase", '_DocTestSuite')) "DocTestCase", '_DocTestSuite'))
self.checkModule('difflib', ignore=("Match",)) self.checkModule('difflib', ignore=("Match",))
def test_decorators(self): def test_cases(self):
self.checkModule('test.pyclbr_input', ignore=['om']) # see test.pyclbr_input for the rationale behind the ignored symbols
self.checkModule('test.pyclbr_input', ignore=['om', 'f'])
def test_nested(self): def test_nested(self):
mb = pyclbr mb = pyclbr