https://github.com/python/cpython/commit/d65e145f9d778efe28eb5154df1ab9d44e06673a
commit: d65e145f9d778efe28eb5154df1ab9d44e06673a
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: encukou <[email protected]>
date: 2024-06-19T09:20:09+02:00
summary:

[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 d8cd0fa4e347f460d0f3277e2392504e61ed087d)

Co-authored-by: Bénédikt Tran <[email protected]>

files:
M Lib/test/pyclbr_input.py
M Lib/test/test_pyclbr.py

diff --git a/Lib/test/pyclbr_input.py b/Lib/test/pyclbr_input.py
index 19ccd62dead8ee..5535edbfa7795b 100644
--- a/Lib/test/pyclbr_input.py
+++ b/Lib/test/pyclbr_input.py
@@ -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
 
@@ -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
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index 46206accbafc36..d409a2d4a312e6 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -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.
@@ -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)
@@ -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

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to