Skip to content

Commit a4872ac

Browse files
committed
Address PR comments
1 parent f36c774 commit a4872ac

File tree

5 files changed

+31
-9
lines changed

5 files changed

+31
-9
lines changed

mypyc/codegen/emitfunc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,10 @@ def visit_get_attr(self, op: GetAttr) -> None:
362362
attr_rtype, decl_cl = cl.attr_details(op.attr)
363363
prefer_method = cl.is_trait and attr_rtype.error_overlap
364364
if cl.get_method(op.attr, prefer_method=prefer_method):
365+
# Properties are essentially methods, so use vtable access for them.
365366
if cl.is_method_final(op.attr):
366367
self.emit_method_call(f"{dest} = ", op.obj, op.attr, [])
367368
else:
368-
# Properties are essentially methods, so use vtable access for them.
369369
version = "_TRAIT" if cl.is_trait else ""
370370
self.emit_line(
371371
"%s = CPY_GET_ATTR%s(%s, %s, %d, %s, %s); /* %s */"

mypyc/irbuild/classdef.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868
get_func_def,
6969
is_constant,
7070
is_dataclass_decorator,
71-
is_final_class,
7271
)
7372
from mypyc.primitives.dict_ops import dict_new_op, dict_set_item_op
7473
from mypyc.primitives.generic_ops import (
@@ -300,7 +299,6 @@ def add_attr(self, lvalue: NameExpr, stmt: AssignmentStmt) -> None:
300299
self.builder.init_final_static(lvalue, value, self.cdef.name)
301300

302301
def finalize(self, ir: ClassIR) -> None:
303-
ir.is_final_class = is_final_class(self.cdef)
304302
attrs_with_defaults, default_assignments = find_attr_initializers(
305303
self.builder, self.cdef, self.skip_attr_default
306304
)

mypyc/irbuild/prepare.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ def build_type_map(
8181
# references even if there are import cycles.
8282
for module, cdef in classes:
8383
class_ir = ClassIR(
84-
cdef.name, module.fullname, is_trait(cdef), is_abstract=cdef.info.is_abstract
84+
cdef.name,
85+
module.fullname,
86+
is_trait(cdef),
87+
is_abstract=cdef.info.is_abstract,
88+
is_final_class=cdef.info.is_final,
8589
)
8690
class_ir.is_ext_class = is_extension_class(cdef)
8791
if class_ir.is_ext_class:

mypyc/irbuild/util.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,14 @@
2727
UnaryExpr,
2828
Var,
2929
)
30+
from mypy.semanal import refers_to_fullname
31+
from mypy.types import FINAL_DECORATOR_NAMES
3032

3133
DATACLASS_DECORATORS = {"dataclasses.dataclass", "attr.s", "attr.attrs"}
3234

3335

3436
def is_final_decorator(d: Expression) -> bool:
35-
return isinstance(d, RefExpr) and d.fullname == "typing.final"
36-
37-
38-
def is_final_class(cdef: ClassDef) -> bool:
39-
return any(is_final_decorator(d) for d in cdef.decorators)
37+
return refers_to_fullname(d, FINAL_DECORATOR_NAMES)
4038

4139

4240
def is_trait_decorator(d: Expression) -> bool:

mypyc/test-data/run-classes.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2522,11 +2522,28 @@ class B:
25222522
def a(self) -> int:
25232523
return 2
25242524

2525+
@property
2526+
def b(self) -> int:
2527+
return self.a() + 2
2528+
2529+
@property
2530+
def c(self) -> int:
2531+
return 3
2532+
2533+
def test_class_final_attribute_basic() -> None:
2534+
assert B().a() == 2
2535+
assert B().b == 4
2536+
assert B().c == 3
2537+
25252538
@final
25262539
class C(B):
25272540
def a(self) -> int:
25282541
return 1
25292542

2543+
@property
2544+
def b(self) -> int:
2545+
return self.a() + 1
2546+
25302547
def fn(cl: B) -> int:
25312548
return cl.a()
25322549

@@ -2535,3 +2552,8 @@ def test_class_final_attribute_inherited() -> None:
25352552
assert fn(C()) == 1
25362553
assert B().a() == 2
25372554
assert fn(B()) == 2
2555+
2556+
assert B().b == 4
2557+
assert C().b == 2
2558+
assert B().c == 3
2559+
assert C().c == 3

0 commit comments

Comments
 (0)