Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions test_descriptor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Base:
def __getattr__(self, name):
print(f"Base.__getattr__({name})")
raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")

class Derived(Base):
@property
def foo(self):
print("Derived.foo property")
return self.bar # This will raise AttributeError

d = Derived()
try:
print(d.foo)
except AttributeError as e:
print(f"AttributeError: {e}")
22 changes: 22 additions & 0 deletions test_fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import torch

class A(torch.nn.Module):
def __init__(self):
super().__init__()

@property
def foo(self):
return self.bar # attr error

a = A()
try:
print(a.foo)
except AttributeError as e:
print(f"AttributeError: {e}")

# Verify that the error message mentions 'bar' and not 'foo'
error_message = str(e)
if "'bar'" in error_message:
print("Test PASSED: Error message correctly identifies the missing attribute 'bar'")
else:
print(f"Test FAILED: Error message does not mention 'bar': {error_message}")
15 changes: 15 additions & 0 deletions test_property_issue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import torch

class A(torch.nn.Module):
def __init__(self):
super().__init__()

@property
def foo(self):
return self.bar # attr error

a = A()
try:
print(a.foo)
except AttributeError as e:
print(f"AttributeError: {e}")
12 changes: 12 additions & 0 deletions torch/nn/modules/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -1941,6 +1941,18 @@ def __getattr__(self, name: str) -> Union[Tensor, "Module"]:
modules = self.__dict__["_modules"]
if name in modules:
return modules[name]

# Check if the attribute exists as a property
# This handles the case where a property raises an AttributeError
property_obj = getattr(type(self), name, None)
if isinstance(property_obj, property):
# Re-raise the original AttributeError from the property
try:
return property_obj.__get__(self, type(self))
except AttributeError as e:
# Re-raise the original AttributeError
raise e

raise AttributeError(
f"'{type(self).__name__}' object has no attribute '{name}'"
)
Expand Down