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