11
11
12
12
glob = 42
13
13
some_var = 12
14
- some_non_assigned_global_var = 11
14
+ some_non_assigned_global_var: int
15
15
some_assigned_global_var = 11
16
16
17
17
class Mine:
@@ -51,6 +51,120 @@ class GenericMine[T: int]:
51
51
pass
52
52
"""
53
53
54
+ TEST_COMPLEX_CLASS_CODE = """
55
+ # The following symbols are defined in ComplexClass
56
+ # without being introduced by a 'global' statement.
57
+ glob_unassigned_meth: Any
58
+ glob_unassigned_meth_pep_695: Any
59
+
60
+ glob_unassigned_async_meth: Any
61
+ glob_unassigned_async_meth_pep_695: Any
62
+
63
+ def glob_assigned_meth(): pass
64
+ def glob_assigned_meth_pep_695[T](): pass
65
+
66
+ async def glob_assigned_async_meth(): pass
67
+ async def glob_assigned_async_meth_pep_695[T](): pass
68
+
69
+ # The following symbols are defined in ComplexClass after
70
+ # being introduced by a 'global' statement (and therefore
71
+ # are not considered as local symbols of ComplexClass).
72
+ glob_unassigned_meth_ignore: Any
73
+ glob_unassigned_meth_pep_695_ignore: Any
74
+
75
+ glob_unassigned_async_meth_ignore: Any
76
+ glob_unassigned_async_meth_pep_695_ignore: Any
77
+
78
+ def glob_assigned_meth_ignore(): pass
79
+ def glob_assigned_meth_pep_695_ignore[T](): pass
80
+
81
+ async def glob_assigned_async_meth_ignore(): pass
82
+ async def glob_assigned_async_meth_pep_695_ignore[T](): pass
83
+
84
+ class ComplexClass:
85
+ a_var = 1234
86
+ a_genexpr = (x for x in [])
87
+ a_lambda = lambda x: x
88
+
89
+ type a_type_alias = int
90
+ type a_type_alias_pep_695[T] = list[T]
91
+
92
+ class a_class: pass
93
+ class a_class_pep_695[T]: pass
94
+
95
+ def a_method(self): pass
96
+ def a_method_pep_695[T](self): pass
97
+
98
+ async def an_async_method(self): pass
99
+ async def an_async_method_pep_695[T](self): pass
100
+
101
+ @classmethod
102
+ def a_classmethod(cls): pass
103
+ @classmethod
104
+ def a_classmethod_pep_695[T](self): pass
105
+
106
+ @classmethod
107
+ async def an_async_classmethod(cls): pass
108
+ @classmethod
109
+ async def an_async_classmethod_pep_695[T](self): pass
110
+
111
+ @staticmethod
112
+ def a_staticmethod(): pass
113
+ @staticmethod
114
+ def a_staticmethod_pep_695[T](self): pass
115
+
116
+ @staticmethod
117
+ async def an_async_staticmethod(): pass
118
+ @staticmethod
119
+ async def an_async_staticmethod_pep_695[T](self): pass
120
+
121
+ # These ones will be considered as methods because of the 'def' although
122
+ # they are *not* valid methods at runtime since they are not decorated
123
+ # with @staticmethod.
124
+ def a_fakemethod(): pass
125
+ def a_fakemethod_pep_695[T](): pass
126
+
127
+ async def an_async_fakemethod(): pass
128
+ async def an_async_fakemethod_pep_695[T](): pass
129
+
130
+ # Check that those are still considered as methods
131
+ # since they are not using the 'global' keyword.
132
+ def glob_unassigned_meth(): pass
133
+ def glob_unassigned_meth_pep_695[T](): pass
134
+
135
+ async def glob_unassigned_async_meth(): pass
136
+ async def glob_unassigned_async_meth_pep_695[T](): pass
137
+
138
+ def glob_assigned_meth(): pass
139
+ def glob_assigned_meth_pep_695[T](): pass
140
+
141
+ async def glob_assigned_async_meth(): pass
142
+ async def glob_assigned_async_meth_pep_695[T](): pass
143
+
144
+ # The following are not picked as local symbols because they are not
145
+ # visible by the class at runtime (this is equivalent to having the
146
+ # definitions outside of the class).
147
+ global glob_unassigned_meth_ignore
148
+ def glob_unassigned_meth_ignore(): pass
149
+ global glob_unassigned_meth_pep_695_ignore
150
+ def glob_unassigned_meth_pep_695_ignore[T](): pass
151
+
152
+ global glob_unassigned_async_meth_ignore
153
+ async def glob_unassigned_async_meth_ignore(): pass
154
+ global glob_unassigned_async_meth_pep_695_ignore
155
+ async def glob_unassigned_async_meth_pep_695_ignore[T](): pass
156
+
157
+ global glob_assigned_meth_ignore
158
+ def glob_assigned_meth_ignore(): pass
159
+ global glob_assigned_meth_pep_695_ignore
160
+ def glob_assigned_meth_pep_695_ignore[T](): pass
161
+
162
+ global glob_assigned_async_meth_ignore
163
+ async def glob_assigned_async_meth_ignore(): pass
164
+ global glob_assigned_async_meth_pep_695_ignore
165
+ async def glob_assigned_async_meth_pep_695_ignore[T](): pass
166
+ """
167
+
54
168
55
169
def find_block (block , name ):
56
170
for ch in block .get_children ():
@@ -63,6 +177,7 @@ class SymtableTest(unittest.TestCase):
63
177
top = symtable .symtable (TEST_CODE , "?" , "exec" )
64
178
# These correspond to scopes in TEST_CODE
65
179
Mine = find_block (top , "Mine" )
180
+
66
181
a_method = find_block (Mine , "a_method" )
67
182
spam = find_block (top , "spam" )
68
183
internal = find_block (spam , "internal" )
@@ -238,6 +353,24 @@ def test_name(self):
238
353
def test_class_info (self ):
239
354
self .assertEqual (self .Mine .get_methods (), ('a_method' ,))
240
355
356
+ top = symtable .symtable (TEST_COMPLEX_CLASS_CODE , "?" , "exec" )
357
+ this = find_block (top , "ComplexClass" )
358
+
359
+ self .assertEqual (this .get_methods (), (
360
+ 'a_method' , 'a_method_pep_695' ,
361
+ 'an_async_method' , 'an_async_method_pep_695' ,
362
+ 'a_classmethod' , 'a_classmethod_pep_695' ,
363
+ 'an_async_classmethod' , 'an_async_classmethod_pep_695' ,
364
+ 'a_staticmethod' , 'a_staticmethod_pep_695' ,
365
+ 'an_async_staticmethod' , 'an_async_staticmethod_pep_695' ,
366
+ 'a_fakemethod' , 'a_fakemethod_pep_695' ,
367
+ 'an_async_fakemethod' , 'an_async_fakemethod_pep_695' ,
368
+ 'glob_unassigned_meth' , 'glob_unassigned_meth_pep_695' ,
369
+ 'glob_unassigned_async_meth' , 'glob_unassigned_async_meth_pep_695' ,
370
+ 'glob_assigned_meth' , 'glob_assigned_meth_pep_695' ,
371
+ 'glob_assigned_async_meth' , 'glob_assigned_async_meth_pep_695' ,
372
+ ))
373
+
241
374
def test_filename_correct (self ):
242
375
### Bug tickler: SyntaxError file name correct whether error raised
243
376
### while parsing or building symbol table.
0 commit comments