|
4 | 4 |
|
5 | 5 | # Fully qualified instead of "from mypy.plugin import ..." to avoid circular import problems. |
6 | 6 | import mypy.plugin |
| 7 | +from mypy import nodes |
7 | 8 | from mypy.maptype import map_instance_to_supertype |
8 | 9 | from mypy.subtypes import is_subtype |
9 | 10 | from mypy.types import ( |
@@ -116,19 +117,22 @@ def array_constructor_callback(ctx: 'mypy.plugin.FunctionContext') -> Type: |
116 | 117 | allowed = _autoconvertible_to_cdata(et, ctx.api) |
117 | 118 | assert len(ctx.arg_types) == 1, \ |
118 | 119 | "The stub of the ctypes.Array constructor should have a single vararg parameter" |
119 | | - for arg_num, arg_type in enumerate(ctx.arg_types[0], 1): |
120 | | - # TODO This causes false errors if the argument list contains *args. |
121 | | - # In a function hook, the type of an *args parameter is the type of the iterable being |
122 | | - # unpacked. However, FunctionContext currently doesn't provide a way to differentiate |
123 | | - # between normal arguments and *args, so the iterable type is considered invalid. |
124 | | - # Once FunctionContext has an API for this, *args should be allowed here if the |
125 | | - # iterable's element type is compatible with the array element type. |
126 | | - if not is_subtype(arg_type, allowed): |
| 120 | + for arg_num, (arg_kind, arg_type) in enumerate(zip(ctx.arg_kinds[0], ctx.arg_types[0]), 1): |
| 121 | + if arg_kind == nodes.ARG_POS and not is_subtype(arg_type, allowed): |
127 | 122 | ctx.api.msg.fail( |
128 | 123 | 'Array constructor argument {} of type "{}"' |
129 | 124 | ' is not convertible to the array element type "{}"' |
130 | 125 | .format(arg_num, arg_type, et), |
131 | 126 | ctx.context) |
| 127 | + elif arg_kind == nodes.ARG_STAR: |
| 128 | + ty = ctx.api.named_generic_type("typing.Iterable", [allowed]) |
| 129 | + if not is_subtype(arg_type, ty): |
| 130 | + ctx.api.msg.fail( |
| 131 | + 'Array constructor argument {} of type "{}"' |
| 132 | + ' is not convertible to the array element type "Iterable[{}]"' |
| 133 | + .format(arg_num, arg_type, et), |
| 134 | + ctx.context) |
| 135 | + |
132 | 136 | return ctx.default_return_type |
133 | 137 |
|
134 | 138 |
|
|
0 commit comments