Skip to content

Commit

Permalink
pythongh-120449: fix test_pyclbr introspection for mangled names (p…
Browse files Browse the repository at this point in the history
…ythonGH-120450)

(cherry picked from commit d8cd0fa)

Co-authored-by: Bénédikt Tran <[email protected]>
  • Loading branch information
picnixz authored and miss-islington committed Jun 18, 2024
1 parent 8c129d9 commit 9ceab52
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 17 deletions.
68 changes: 60 additions & 8 deletions Lib/test/pyclbr_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ class B (object):
def bm(self): pass

class C (B):
foo = Other().foo
om = Other.om

d = 10

# XXX: 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().
# The pyclbr.py module gets this right as it parses the text.
# This one is correctly considered by both test_pyclbr.py and pyclbr.py
# as a non-method of C.
foo = Other().foo

# 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

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

@classmethod
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
24 changes: 15 additions & 9 deletions Lib/test/test_pyclbr.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def ismethod(oclass, obj, name):

objname = obj.__name__
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

# Make sure the toplevel functions and classes are the same.
Expand Down Expand Up @@ -111,12 +112,16 @@ def ismethod(oclass, obj, name):
for m in py_item.__dict__.keys():
if ismethod(py_item, getattr(py_item, m), m):
actualMethods.append(m)
foundMethods = []
for m in value.methods.keys():
if m[:2] == '__' and m[-2:] != '__':
foundMethods.append('_'+name+m)
else:
foundMethods.append(m)

if stripped_typename := name.lstrip('_'):
foundMethods = []
for m in value.methods.keys():
if m.startswith('__') and not m.endswith('__'):
foundMethods.append(f"_{stripped_typename}{m}")
else:
foundMethods.append(m)
else:
foundMethods = list(value.methods.keys())

try:
self.assertListEq(foundMethods, actualMethods, ignore)
Expand Down Expand Up @@ -150,8 +155,9 @@ def test_easy(self):
"DocTestCase", '_DocTestSuite'))
self.checkModule('difflib', ignore=("Match",))

def test_decorators(self):
self.checkModule('test.pyclbr_input', ignore=['om'])
def test_cases(self):
# see test.pyclbr_input for the rationale behind the ignored symbols
self.checkModule('test.pyclbr_input', ignore=['om', 'f'])

def test_nested(self):
mb = pyclbr
Expand Down

0 comments on commit 9ceab52

Please sign in to comment.