Home > Mobile >  type hinting an array
type hinting an array

Time:09-16

Consider the following minimal example:

from array import array


def foo(arr: array) -> None:
    print(arr)

I have a function which takes an array argument. My project is statically typed and uses mypy. Mypy complains that: Mypy: Missing type parameters for generic type "array".

Could you help me understand how am I supposed to type hint the argument? I can't seem to find documentation on the subject. I can't understand why would mypy decide this is a generic type.

To clarify, to my understanding, the type hint I used works, but mypy still complains as it considers it as a generic type, and wants the type of the "elements". Am I missing something, or is it a bug in mypy?

Related to this: What's the type hint for an array?

CodePudding user response:

Most of the standard library is not type annotated. mypy is using the stubs for the standard library from the typeshed project (which along with the standard library, also contains annotations for popular third-party library as provided by various contributers). For the array module, you can see that it is type annotated as generic:

import sys
from typing import Any, BinaryIO, Generic, Iterable, MutableSequence, Tuple, TypeVar, Union, overload
from typing_extensions import Literal

_IntTypeCode = Literal["b", "B", "h", "H", "i", "I", "l", "L", "q", "Q"]
_FloatTypeCode = Literal["f", "d"]
_UnicodeTypeCode = Literal["u"]
_TypeCode = Union[_IntTypeCode, _FloatTypeCode, _UnicodeTypeCode]

_T = TypeVar("_T", int, float, str)

typecodes: str

class array(MutableSequence[_T], Generic[_T]):
    typecode: _TypeCode
    itemsize: int
    @overload
    def __init__(self: array[int], typecode: _IntTypeCode, __initializer: bytes | Iterable[_T] = ...) -> None: ...
    @overload
    def __init__(self: array[float], typecode: _FloatTypeCode, __initializer: bytes | Iterable[_T] = ...) -> None: ...
    @overload
    def __init__(self: array[str], typecode: _UnicodeTypeCode, __initializer: bytes | Iterable[_T] = ...) -> None: ...
    @overload
    def __init__(self, typecode: str, __initializer: bytes | Iterable[_T] = ...) -> None: ...
    def append(self, __v: _T) -> None: ...

    ...

The solution is to use MutableSequence as noted as answered in the question you linked to. Note, since Python 3.9 , typing.MutableSequence (along with things like typing.List and typing.Dict) have been deprecated, and the types themselves support generics, so use import collections and collections.abc.MutableSequence

  • Related