Skip to content

Commit

Permalink
Fix bug with read-only implementations of attributes on dataclasses.
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-mitchell committed Mar 5, 2024
1 parent 3982039 commit 3cbbd47
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
11 changes: 10 additions & 1 deletion pure_interface/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,11 +402,20 @@ def _ensure_everything_is_abstract(attributes):
return namespace, functions, interface_method_signatures, interface_attribute_names


def _readonly_attribute(name, namespace):
# if the attribute is a property with a getter but no setter then it is read-only
prop = namespace.get(name)
if isinstance(prop, property):
if prop.fset is None:
return True
return False


def _ensure_annotations(names, namespace):
# annotations need to be kept in order, add base-class names first
annotations = {}
for name in names:
if name not in annotations:
if name not in annotations and not _readonly_attribute(name, namespace):
annotations[name] = Any
annotations.update(namespace.get('__annotations__', {}))
namespace['__annotations__'] = annotations
Expand Down
16 changes: 16 additions & 0 deletions tests/test_dataclass_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,19 @@ def foo(self):
f = Foo(a=1, b='two')
self.assertEqual(1, f.a)
self.assertEqual('two', f.b)

def test_read_only_attr(self):
@dataclass
class RoFoo(IFoo):
c: int

@property
def b(self):
return 'str'

def foo(self):
return 'a={}, b={}, c={}'.format(self.a, self.b, self.c)

f = RoFoo(a=1, c=3)
self.assertEqual(1, f.a)
self.assertEqual('str', f.b)

0 comments on commit 3cbbd47

Please sign in to comment.