Skip to content

Commit c67dffa

Browse files
committed
fix MapAttribute support
1 parent e3e51a6 commit c67dffa

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

pynamodb_mypy/plugin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def get_method_signature_hook(self, fullname: str
3030
def _is_attribute_type_node(node: mypy.nodes.Node) -> bool:
3131
return (
3232
isinstance(node, mypy.nodes.TypeInfo) and
33-
any(base.type.fullname == ATTR_FULL_NAME for base in node.bases)
33+
node.has_base(ATTR_FULL_NAME)
3434
)
3535

3636

@@ -84,7 +84,7 @@ def _get_method_sig_hook(ctx: mypy.plugin.MethodSigContext) -> mypy.types.Callab
8484
(instance_type, owner_type) = sig.arg_types
8585
except ValueError:
8686
return sig
87-
if not isinstance(instance_type, mypy.types.AnyType): # instance attribute access
87+
if isinstance(instance_type, mypy.types.NoneType): # class attribute access
8888
return sig
8989
return sig.copy_modified(ret_type=_make_optional(sig.ret_type))
9090

tests/test_plugin.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ class MyModel(Model):
1414
reveal_type(MyModel().my_not_nullable_attr) # N: Revealed type is 'builtins.float*'
1515
1616
my_model = MyModel()
17-
my_model.my_attr = None
17+
my_model.my_attr = None # E: Incompatible types in assignment (expression has type "None", variable has type "float") [assignment]
1818
my_model.my_nullable_attr = None
19-
my_model.my_not_nullable_attr = None
19+
my_model.my_not_nullable_attr = None # E: Incompatible types in assignment (expression has type "None", variable has type "float") [assignment]
2020
my_model.my_attr = 42
2121
my_model.my_nullable_attr = 42
2222
my_model.my_not_nullable_attr = 42
23-
""")
23+
""") # noqa: E501
2424

2525

2626
def test_unicode_attribute(assert_mypy_output):
@@ -42,6 +42,25 @@ class MyModel(Model):
4242
""")
4343

4444

45+
def test_map_attribute(assert_mypy_output):
46+
assert_mypy_output("""
47+
from pynamodb.attributes import MapAttribute, UnicodeAttribute
48+
from pynamodb.models import Model
49+
50+
class MyMapAttribute(MapAttribute):
51+
my_sub_attr = UnicodeAttribute()
52+
53+
class MyModel(Model):
54+
my_attr = MyMapAttribute()
55+
my_nullable_attr = MyMapAttribute(null=True)
56+
57+
reveal_type(MyModel.my_attr) # N: Revealed type is '__main__.MyMapAttribute'
58+
reveal_type(MyModel.my_nullable_attr) # N: Revealed type is '__main__.MyMapAttribute[None]'
59+
reveal_type(MyModel().my_attr) # N: Revealed type is '__main__.MyMapAttribute'
60+
reveal_type(MyModel().my_nullable_attr) # N: Revealed type is 'Union[__main__.MyMapAttribute[None], None]'
61+
""")
62+
63+
4564
def test_custom_attribute(assert_mypy_output):
4665
assert_mypy_output("""
4766
from pynamodb.attributes import Attribute

0 commit comments

Comments
 (0)