Skip to content

Commit 14abb4a

Browse files
authored
Handle unexpected Model.__init__ sig (#3)
1 parent 8ae05ad commit 14abb4a

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

pynamodb_mypy/plugin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ def _get_function_signature_hook__pynamodb_model__init__(self, ctx: FunctionSigC
122122
hash_key_idx = ctx.default_signature.arg_names.index("hash_key")
123123
range_key_idx = ctx.default_signature.arg_names.index("range_key")
124124
kwargs_idx = ctx.default_signature.arg_kinds.index(ArgKind.ARG_STAR2)
125-
except IndexError: # pragma: no cover
125+
except ValueError:
126+
ctx.api.fail(f"Unexpected signature '{ctx.default_signature}' for a PynamoDB model initializer: "
127+
"expecting 'hash_key', 'range_key' and a keywords argument", ctx.context)
126128
return ctx.default_signature
127129
else:
128130
arg_kinds = ctx.default_signature.arg_kinds.copy()

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = pynamodb-mypy
3-
version = 0.1.0
3+
version = 0.1.1
44
description = mypy plugin for PynamoDB
55
long_description = file: README.md
66
long_description_content_type = text/markdown

tests/test_plugin.py

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
from __future__ import annotations
22

3-
from unittest.mock import Mock
4-
53
from .mypy_helpers import MypyAssert
64

75

8-
def test_init(assert_mypy_output: MypyAssert) -> None:
6+
def test_model_init(assert_mypy_output: MypyAssert) -> None:
97
assert_mypy_output(
108
"""
119
from pynamodb.attributes import NumberAttribute
@@ -27,7 +25,7 @@ class MyModel(Model):
2725
)
2826

2927

30-
def test_init__no_attributes(assert_mypy_output: MypyAssert) -> None:
28+
def test_model_init__no_attributes(assert_mypy_output: MypyAssert) -> None:
3129
assert_mypy_output(
3230
"""
3331
from pynamodb.attributes import NumberAttribute
@@ -45,6 +43,47 @@ class MyModel(Model):
4543
)
4644

4745

46+
def test_model_init__custom_empty(assert_mypy_output: MypyAssert) -> None:
47+
assert_mypy_output(
48+
"""
49+
from pynamodb.attributes import NumberAttribute
50+
from pynamodb.models import Model
51+
52+
class MyModel(Model):
53+
my_hash_key = NumberAttribute(hash_key=True)
54+
my_range_key = NumberAttribute(range_key=True)
55+
my_attr = NumberAttribute()
56+
57+
def __init__(self) -> None:
58+
...
59+
60+
MyModel('foo', 'bar') # E: Unexpected signature 'def () -> __main__.MyModel' for a PynamoDB model initializer: expecting 'hash_key', 'range_key' and a keywords argument [misc]
61+
# E: Too many arguments for "MyModel" [call-arg]
62+
"""
63+
)
64+
65+
66+
def test_model_init__custom_all_args(assert_mypy_output: MypyAssert) -> None:
67+
assert_mypy_output(
68+
"""
69+
from typing import Any
70+
71+
from pynamodb.attributes import NumberAttribute
72+
from pynamodb.models import Model
73+
74+
class MyModel(Model):
75+
my_hash_key = NumberAttribute(hash_key=True)
76+
my_range_key = NumberAttribute(range_key=True)
77+
my_attr = NumberAttribute()
78+
79+
def __init__(self, *args: Any, **kwargs: Any) -> None:
80+
...
81+
82+
MyModel(unknown=42) # E: Unexpected signature 'def (*args: Any, **kwargs: Any) -> __main__.MyModel' for a PynamoDB model initializer: expecting 'hash_key', 'range_key' and a keywords argument [misc]
83+
"""
84+
)
85+
86+
4887
def test_number_attribute(assert_mypy_output: MypyAssert) -> None:
4988
assert_mypy_output(
5089
"""

0 commit comments

Comments
 (0)