The Python 3.15 improved error message for nested attribute access doesn't seem to work on properties.
Rationale
Take the example from the What's new in Python 3.15 docs:
from dataclasses import dataclass @dataclass class Circle: radius: float @property def area(self) -> float: return pi * self.radius**2 class Container: def __init__(self, inner: Circle) -> None: self.inner = inner circle = Circle(radius=4.0) container = Container(circle) print(container.area)
Running it with the CPython main branch or Python 3.15.0a1 through Python 3.15.0a7 (with uv) produces the following error:
Traceback (most recent call last): File "/Users/rodrigogs/Documents/cpython/../tmp/circle.py", line 17, in <module> print(container.area) ^^^^^^^^^^^^^^ AttributeError: 'Container' object has no attribute 'area'
If you remove @property or if you try accessing container.radius instead, you get the respective improved messages:
# After removing `@property` from `area`: Traceback (most recent call last): File "/Users/rodrigogs/Documents/cpython/../tmp/circle_no_prop.py", line 16, in <module> print(container.area) ^^^^^^^^^^^^^^ AttributeError: 'Container' object has no attribute 'area'. Did you mean: 'inner.area'? # --- # Accessing `radius` instead of the property `area`: Traceback (most recent call last): File "/Users/rodrigogs/Documents/cpython/../tmp/circle_radius.py", line 17, in <module> print(container.radius) ^^^^^^^^^^^^^^^^ AttributeError: 'Container' object has no attribute 'radius'. Did you mean: 'inner.radius'?
Helper scripts for easier testing
circle.py — original example that doesn't work
from dataclasses import dataclass @dataclass class Circle: radius: float @property def area(self) -> float: return pi * self.radius**2 class Container: def __init__(self, inner: Circle) -> None: self.inner = inner circle = Circle(radius=4.0) container = Container(circle) print(container.area)
circle_radius.py — accessing radius works
from dataclasses import dataclass @dataclass class Circle: radius: float @property def area(self) -> float: return pi * self.radius**2 class Container: def __init__(self, inner: Circle) -> None: self.inner = inner circle = Circle(radius=4.0) container = Container(circle) print(container.radius)
circle_no_prop.py — removing the property works
from dataclasses import dataclass @dataclass class Circle: radius: float # @property def area(self) -> float: return pi * self.radius**2 class Container: def __init__(self, inner: Circle) -> None: self.inner = inner circle = Circle(radius=4.0) container = Container(circle) print(container.area)
CPython versions tested on:
3.15, CPython main branch
Operating systems tested on:
macOS