Skip to content

Commit 73bfc7d

Browse files
author
Scott Sanderson
authored
Merge pull request #31 from ssanderson/fix-default-property
Fix default property
2 parents b1dabab + cc9a218 commit 73bfc7d

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

interface/default.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ def non_member_attributes(defaults, members):
5252
# staticmethods can't use attributes of the interface.
5353
continue
5454

55+
elif isinstance(impl, property):
56+
impl = impl.fget
57+
5558
self_name = TypedSignature(impl).first_argument_name
5659
if self_name is None:
5760
# No parameters.
@@ -73,13 +76,20 @@ def accessed_attributes_of_local(f, local_name):
7376
The analysis performed by this function is conservative, meaning that
7477
it's not guaranteed to find **all** attributes used.
7578
"""
79+
try:
80+
instrs = dis.get_instructions(f)
81+
except TypeError:
82+
# Got a default wrapping an object that's not a python function. Be
83+
# conservative and assume this is safe.
84+
return set()
85+
7686
used = set()
7787
# Find sequences of the form: LOAD_FAST(local_name), LOAD_ATTR(<name>).
7888
# This will find all usages of the form ``local_name.<name>``.
7989
#
8090
# It will **NOT** find usages in which ``local_name`` is aliased to
8191
# another name.
82-
for first, second in sliding_window(dis.get_instructions(f), 2):
92+
for first, second in sliding_window(instrs, 2):
8393
if first.opname == 'LOAD_FAST' and first.argval == local_name:
8494
if second.opname in ('LOAD_ATTR', 'LOAD_METHOD', 'STORE_ATTR'):
8595
used.add(second.argval)

interface/tests/test_interface.py

+23
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,29 @@ def method2(self):
528528
assert C().has_default() == 3
529529

530530

531+
def test_default_property():
532+
533+
class IFace(Interface): # pragma: nocover
534+
535+
@default
536+
@property
537+
def default_prop(self):
538+
return True
539+
540+
class C(implements(IFace)): # pragma: nocover
541+
pass
542+
543+
assert C().default_prop
544+
545+
class D(implements(IFace)):
546+
547+
@property
548+
def default_prop(self):
549+
return False
550+
551+
assert not D().default_prop
552+
553+
531554
def test_override_default():
532555

533556
class IFace(Interface): # pragma: nocover

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def install_requires():
3030

3131
setup(
3232
name='python-interface',
33-
version='1.5.0',
33+
version='1.5.2',
3434
description="Pythonic Interface definitions",
3535
author="Scott Sanderson",
3636
author_email="[email protected]",

0 commit comments

Comments
 (0)