Skip to content

Commit 2be7299

Browse files
authored
Fix type hinting bug for renamed class attributes (pyccel#2113)
Fix declaration of class attributes with name conflicts using type annotations. Fixes pyccel#2111 . The attribute created via the type annotation was not passing the original Python name to the scope which lead to it not being found later. As a result a second (unnecessary but identical) variable was created.
1 parent 7024366 commit 2be7299

File tree

4 files changed

+22
-14
lines changed

4 files changed

+22
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ All notable changes to this project will be documented in this file.
9494
- #2082 : Allow the use of a list comprehension to initialise an array.
9595
- #2094 : Fix slicing of array allocated in an if block.
9696
- #2085 : Fix calling class methods before they are defined.
97+
- #2111 : Fix declaration of class attributes with name conflicts using type annotations.
9798

9899
### Changed
99100

pyccel/parser/semantic.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3283,10 +3283,11 @@ def _visit_Assign(self, expr):
32833283
cls_def = semantic_lhs_var.lhs.cls_base
32843284
insert_scope = cls_def.scope
32853285
cls_def.add_new_attribute(semantic_lhs_var)
3286+
lhs = lhs.name.name[-1]
32863287
else:
32873288
insert_scope = self.scope
3289+
lhs = lhs.name
32883290

3289-
lhs = lhs.name
32903291
if semantic_lhs_var.class_type is TypeAlias():
32913292
if not isinstance(rhs, SyntacticTypeAnnotation):
32923293
pyccel_stage.set_stage('syntactic')
@@ -3297,7 +3298,7 @@ def _visit_Assign(self, expr):
32973298
return EmptyNode()
32983299

32993300
try:
3300-
insert_scope.insert_variable(semantic_lhs_var)
3301+
insert_scope.insert_variable(semantic_lhs_var, lhs)
33013302
except RuntimeError as e:
33023303
errors.report(e, symbol=expr, severity='error')
33033304

tests/epyccel/classes/classes_7.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
class A:
44
def __init__(self : 'A', x : int):
5-
self.x = x
5+
self.data : int = x
66

77
def update(self : 'A', x : int):
8-
self.x = x
8+
self.data = x
99

1010
def get_A():
1111
return A(4)
@@ -15,15 +15,6 @@ def get_A_int():
1515

1616
def get_x_from_A(a : 'A' = None):
1717
if a is not None:
18-
return a.x
18+
return a.data
1919
else:
2020
return 5
21-
22-
if __name__ == '__main__':
23-
print(get_A().x)
24-
print(get_x_from_A())
25-
print(get_x_from_A(get_A()))
26-
x = get_A()
27-
x.update(10)
28-
print(get_x_from_A(x))
29-
x, p = get_A_int()

tests/epyccel/test_epyccel_classes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,21 @@ def test_classes_6(language):
210210
assert p_py.get_attributes(3) == p_l.get_attributes(3)
211211
assert p_py.get_attributes(4.5) == p_l.get_attributes(4.5)
212212

213+
def test_classes_7(language):
214+
import classes.classes_7 as mod
215+
modnew = epyccel(mod, language = language)
216+
217+
p_py = mod.get_A()
218+
p_l = modnew.get_A()
219+
220+
assert mod.get_x_from_A() == modnew.get_x_from_A()
221+
assert mod.get_x_from_A(p_py) == modnew.get_x_from_A(p_l)
222+
223+
p_py.update(10)
224+
p_l.update(10)
225+
226+
assert mod.get_x_from_A(p_py) == modnew.get_x_from_A(p_l)
227+
213228
def test_classes_8(language):
214229
import classes.classes_8 as mod
215230
modnew = epyccel(mod, language = language)

0 commit comments

Comments
 (0)