def numpy_core_numerictypes_transform():
    # TODO: Uniformize the generic API with the ndarray one.
    #       According to numpy doc the generic object should expose
    #       the same API than ndarray. This has been done here partially
    #       through the astype method.
    generic_src = """
    class generic(object):
        def __init__(self, value):
            self.T = np.ndarray([0, 0])
            self.base = None
            self.data = None
            self.dtype = None
            self.flags = None
            # Should be a numpy.flatiter instance but not available for now
            # Putting an array instead so that iteration and indexing are authorized
            self.flat = np.ndarray([0, 0])
            self.imag = None
            self.itemsize = None
            self.nbytes = None
            self.ndim = None
            self.real = None
            self.size = None
            self.strides = None

        def all(self): return uninferable
        def any(self): return uninferable
        def argmax(self): return uninferable
        def argmin(self): return uninferable
        def argsort(self): return uninferable
        def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): return np.ndarray([0, 0])
        def base(self): return uninferable
        def byteswap(self): return uninferable
        def choose(self): return uninferable
        def clip(self): return uninferable
        def compress(self): return uninferable
        def conj(self): return uninferable
        def conjugate(self): return uninferable
        def copy(self): return uninferable
        def cumprod(self): return uninferable
        def cumsum(self): return uninferable
        def data(self): return uninferable
        def diagonal(self): return uninferable
        def dtype(self): return uninferable
        def dump(self): return uninferable
        def dumps(self): return uninferable
        def fill(self): return uninferable
        def flags(self): return uninferable
        def flat(self): return uninferable
        def flatten(self): return uninferable
        def getfield(self): return uninferable
        def imag(self): return uninferable
        def item(self): return uninferable
        def itemset(self): return uninferable
        def itemsize(self): return uninferable
        def max(self): return uninferable
        def mean(self): return uninferable
        def min(self): return uninferable
        def nbytes(self): return uninferable
        def ndim(self): return uninferable
        def newbyteorder(self): return uninferable
        def nonzero(self): return uninferable
        def prod(self): return uninferable
        def ptp(self): return uninferable
        def put(self): return uninferable
        def ravel(self): return uninferable
        def real(self): return uninferable
        def repeat(self): return uninferable
        def reshape(self): return uninferable
        def resize(self): return uninferable
        def round(self): return uninferable
        def searchsorted(self): return uninferable
        def setfield(self): return uninferable
        def setflags(self): return uninferable
        def shape(self): return uninferable
        def size(self): return uninferable
        def sort(self): return uninferable
        def squeeze(self): return uninferable
        def std(self): return uninferable
        def strides(self): return uninferable
        def sum(self): return uninferable
        def swapaxes(self): return uninferable
        def take(self): return uninferable
        def tobytes(self): return uninferable
        def tofile(self): return uninferable
        def tolist(self): return uninferable
        def tostring(self): return uninferable
        def trace(self): return uninferable
        def transpose(self): return uninferable
        def var(self): return uninferable
        def view(self): return uninferable
        """
    if numpy_supports_type_hints():
        generic_src += """
        @classmethod
        def __class_getitem__(cls, value):
            return cls
        """
    return parse(generic_src + """
    class dtype(object):
        def __init__(self, obj, align=False, copy=False):
            self.alignment = None
            self.base = None
            self.byteorder = None
            self.char = None
            self.descr = None
            self.fields = None
            self.flags = None
            self.hasobject = None
            self.isalignedstruct = None
            self.isbuiltin = None
            self.isnative = None
            self.itemsize = None
            self.kind = None
            self.metadata = None
            self.name = None
            self.names = None
            self.num = None
            self.shape = None
            self.str = None
            self.subdtype = None
            self.type = None

        def newbyteorder(self, new_order='S'): return uninferable
        def __neg__(self): return uninferable

    class busdaycalendar(object):
        def __init__(self, weekmask='1111100', holidays=None):
            self.holidays = None
            self.weekmask = None

    class flexible(generic): pass
    class bool_(generic): pass
    class number(generic):
        def __neg__(self): return uninferable
    class datetime64(generic):
        def __init__(self, nb, unit=None): pass


    class void(flexible):
        def __init__(self, *args, **kwargs):
            self.base = None
            self.dtype = None
            self.flags = None
        def getfield(self): return uninferable
        def setfield(self): return uninferable


    class character(flexible): pass


    class integer(number):
        def __init__(self, value):
           self.denominator = None
           self.numerator = None


    class inexact(number): pass


    class str_(str, character):
        def maketrans(self, x, y=None, z=None): return uninferable


    class bytes_(bytes, character):
        def fromhex(self, string): return uninferable
        def maketrans(self, frm, to): return uninferable


    class signedinteger(integer): pass


    class unsignedinteger(integer): pass


    class complexfloating(inexact): pass


    class floating(inexact): pass


    class float64(floating, float):
        def fromhex(self, string): return uninferable


    class uint64(unsignedinteger): pass
    class complex64(complexfloating): pass
    class int16(signedinteger): pass
    class float96(floating): pass
    class int8(signedinteger): pass
    class uint32(unsignedinteger): pass
    class uint8(unsignedinteger): pass
    class _typedict(dict): pass
    class complex192(complexfloating): pass
    class timedelta64(signedinteger):
        def __init__(self, nb, unit=None): pass
    class int32(signedinteger): pass
    class uint16(unsignedinteger): pass
    class float32(floating): pass
    class complex128(complexfloating, complex): pass
    class float16(floating): pass
    class int64(signedinteger): pass

    buffer_type = memoryview
    bool8 = bool_
    byte = int8
    bytes0 = bytes_
    cdouble = complex128
    cfloat = complex128
    clongdouble = complex192
    clongfloat = complex192
    complex_ = complex128
    csingle = complex64
    double = float64
    float_ = float64
    half = float16
    int0 = int32
    int_ = int32
    intc = int32
    intp = int32
    long = int32
    longcomplex = complex192
    longdouble = float96
    longfloat = float96
    longlong = int64
    object0 = object_
    object_ = object_
    short = int16
    single = float32
    singlecomplex = complex64
    str0 = str_
    string_ = bytes_
    ubyte = uint8
    uint = uint32
    uint0 = uint32
    uintc = uint32
    uintp = uint32
    ulonglong = uint64
    unicode = str_
    unicode_ = str_
    ushort = uint16
    void0 = void
    """)
Ejemplo n.º 2
0
class NumpyBrainNdarrayTest(unittest.TestCase):
    """
    Test that calls to numpy functions returning arrays are correctly inferred
    """

    ndarray_returning_ndarray_methods = (
        "__abs__",
        "__add__",
        "__and__",
        "__array__",
        "__array_wrap__",
        "__copy__",
        "__deepcopy__",
        "__eq__",
        "__floordiv__",
        "__ge__",
        "__gt__",
        "__iadd__",
        "__iand__",
        "__ifloordiv__",
        "__ilshift__",
        "__imod__",
        "__imul__",
        "__invert__",
        "__ior__",
        "__ipow__",
        "__irshift__",
        "__isub__",
        "__itruediv__",
        "__ixor__",
        "__le__",
        "__lshift__",
        "__lt__",
        "__matmul__",
        "__mod__",
        "__mul__",
        "__ne__",
        "__neg__",
        "__or__",
        "__pos__",
        "__pow__",
        "__rshift__",
        "__sub__",
        "__truediv__",
        "__xor__",
        "all",
        "any",
        "argmax",
        "argmin",
        "argpartition",
        "argsort",
        "astype",
        "byteswap",
        "choose",
        "clip",
        "compress",
        "conj",
        "conjugate",
        "copy",
        "cumprod",
        "cumsum",
        "diagonal",
        "dot",
        "flatten",
        "getfield",
        "max",
        "mean",
        "min",
        "newbyteorder",
        "prod",
        "ptp",
        "ravel",
        "repeat",
        "reshape",
        "round",
        "searchsorted",
        "squeeze",
        "std",
        "sum",
        "swapaxes",
        "take",
        "trace",
        "transpose",
        "var",
        "view",
    )

    def _inferred_ndarray_method_call(self, func_name):
        node = builder.extract_node(
            f"""
        import numpy as np
        test_array = np.ndarray((2, 2))
        test_array.{func_name:s}()
        """
        )
        return node.infer()

    def _inferred_ndarray_attribute(self, attr_name):
        node = builder.extract_node(
            f"""
        import numpy as np
        test_array = np.ndarray((2, 2))
        test_array.{attr_name:s}
        """
        )
        return node.infer()

    def test_numpy_function_calls_inferred_as_ndarray(self):
        """
        Test that some calls to numpy functions are inferred as numpy.ndarray
        """
        licit_array_types = ".ndarray"
        for func_ in self.ndarray_returning_ndarray_methods:
            with self.subTest(typ=func_):
                inferred_values = list(self._inferred_ndarray_method_call(func_))
                self.assertTrue(
                    len(inferred_values) == 1,
                    msg=f"Too much inferred value for {func_:s}",
                )
                self.assertTrue(
                    inferred_values[-1].pytype() in licit_array_types,
                    msg=f"Illicit type for {func_:s} ({inferred_values[-1].pytype()})",
                )

    def test_numpy_ndarray_attribute_inferred_as_ndarray(self):
        """
        Test that some numpy ndarray attributes are inferred as numpy.ndarray
        """
        licit_array_types = ".ndarray"
        for attr_ in ("real", "imag", "shape", "T"):
            with self.subTest(typ=attr_):
                inferred_values = list(self._inferred_ndarray_attribute(attr_))
                self.assertTrue(
                    len(inferred_values) == 1,
                    msg=f"Too much inferred value for {attr_:s}",
                )
                self.assertTrue(
                    inferred_values[-1].pytype() in licit_array_types,
                    msg=f"Illicit type for {attr_:s} ({inferred_values[-1].pytype()})",
                )

    @unittest.skipUnless(
        HAS_NUMPY and numpy_supports_type_hints(),
        f"This test requires the numpy library with a version above {NUMPY_VERSION_TYPE_HINTS_SUPPORT}",
    )
    def test_numpy_ndarray_class_support_type_indexing(self):
        """
        Test that numpy ndarray class can be subscripted (type hints)
        """
        src = """
        import numpy as np
        np.ndarray[int]
        """
        node = builder.extract_node(src)
        cls_node = node.inferred()[0]
        self.assertIsInstance(cls_node, nodes.ClassDef)
        self.assertEqual(cls_node.name, "ndarray")
Ejemplo n.º 3
0
def infer_numpy_ndarray(node, context=None):
    ndarray = """
    class ndarray(object):
        def __init__(self, shape, dtype=float, buffer=None, offset=0,
                     strides=None, order=None):
            self.T = numpy.ndarray([0, 0])
            self.base = None
            self.ctypes = None
            self.data = None
            self.dtype = None
            self.flags = None
            # Should be a numpy.flatiter instance but not available for now
            # Putting an array instead so that iteration and indexing are authorized
            self.flat = np.ndarray([0, 0])
            self.imag = np.ndarray([0, 0])
            self.itemsize = None
            self.nbytes = None
            self.ndim = None
            self.real = np.ndarray([0, 0])
            self.shape = numpy.ndarray([0, 0])
            self.size = None
            self.strides = None

        def __abs__(self): return numpy.ndarray([0, 0])
        def __add__(self, value): return numpy.ndarray([0, 0])
        def __and__(self, value): return numpy.ndarray([0, 0])
        def __array__(self, dtype=None): return numpy.ndarray([0, 0])
        def __array_wrap__(self, obj): return numpy.ndarray([0, 0])
        def __contains__(self, key): return True
        def __copy__(self): return numpy.ndarray([0, 0])
        def __deepcopy__(self, memo): return numpy.ndarray([0, 0])
        def __divmod__(self, value): return (numpy.ndarray([0, 0]), numpy.ndarray([0, 0]))
        def __eq__(self, value): return numpy.ndarray([0, 0])
        def __float__(self): return 0.
        def __floordiv__(self): return numpy.ndarray([0, 0])
        def __ge__(self, value): return numpy.ndarray([0, 0])
        def __getitem__(self, key): return uninferable
        def __gt__(self, value): return numpy.ndarray([0, 0])
        def __iadd__(self, value): return numpy.ndarray([0, 0])
        def __iand__(self, value): return numpy.ndarray([0, 0])
        def __ifloordiv__(self, value): return numpy.ndarray([0, 0])
        def __ilshift__(self, value): return numpy.ndarray([0, 0])
        def __imod__(self, value): return numpy.ndarray([0, 0])
        def __imul__(self, value): return numpy.ndarray([0, 0])
        def __int__(self): return 0
        def __invert__(self): return numpy.ndarray([0, 0])
        def __ior__(self, value): return numpy.ndarray([0, 0])
        def __ipow__(self, value): return numpy.ndarray([0, 0])
        def __irshift__(self, value): return numpy.ndarray([0, 0])
        def __isub__(self, value): return numpy.ndarray([0, 0])
        def __itruediv__(self, value): return numpy.ndarray([0, 0])
        def __ixor__(self, value): return numpy.ndarray([0, 0])
        def __le__(self, value): return numpy.ndarray([0, 0])
        def __len__(self): return 1
        def __lshift__(self, value): return numpy.ndarray([0, 0])
        def __lt__(self, value): return numpy.ndarray([0, 0])
        def __matmul__(self, value): return numpy.ndarray([0, 0])
        def __mod__(self, value): return numpy.ndarray([0, 0])
        def __mul__(self, value): return numpy.ndarray([0, 0])
        def __ne__(self, value): return numpy.ndarray([0, 0])
        def __neg__(self): return numpy.ndarray([0, 0])
        def __or__(self, value): return numpy.ndarray([0, 0])
        def __pos__(self): return numpy.ndarray([0, 0])
        def __pow__(self): return numpy.ndarray([0, 0])
        def __repr__(self): return str()
        def __rshift__(self): return numpy.ndarray([0, 0])
        def __setitem__(self, key, value): return uninferable
        def __str__(self): return str()
        def __sub__(self, value): return numpy.ndarray([0, 0])
        def __truediv__(self, value): return numpy.ndarray([0, 0])
        def __xor__(self, value): return numpy.ndarray([0, 0])
        def all(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0])
        def any(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0])
        def argmax(self, axis=None, out=None): return np.ndarray([0, 0])
        def argmin(self, axis=None, out=None): return np.ndarray([0, 0])
        def argpartition(self, kth, axis=-1, kind='introselect', order=None): return np.ndarray([0, 0])
        def argsort(self, axis=-1, kind='quicksort', order=None): return np.ndarray([0, 0])
        def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): return np.ndarray([0, 0])
        def byteswap(self, inplace=False): return np.ndarray([0, 0])
        def choose(self, choices, out=None, mode='raise'): return np.ndarray([0, 0])
        def clip(self, min=None, max=None, out=None): return np.ndarray([0, 0])
        def compress(self, condition, axis=None, out=None): return np.ndarray([0, 0])
        def conj(self): return np.ndarray([0, 0])
        def conjugate(self): return np.ndarray([0, 0])
        def copy(self, order='C'): return np.ndarray([0, 0])
        def cumprod(self, axis=None, dtype=None, out=None): return np.ndarray([0, 0])
        def cumsum(self, axis=None, dtype=None, out=None): return np.ndarray([0, 0])
        def diagonal(self, offset=0, axis1=0, axis2=1): return np.ndarray([0, 0])
        def dot(self, b, out=None): return np.ndarray([0, 0])
        def dump(self, file): return None
        def dumps(self): return str()
        def fill(self, value): return None
        def flatten(self, order='C'): return np.ndarray([0, 0])
        def getfield(self, dtype, offset=0): return np.ndarray([0, 0])
        def item(self, *args): return uninferable
        def itemset(self, *args): return None
        def max(self, axis=None, out=None): return np.ndarray([0, 0])
        def mean(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0])
        def min(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0])
        def newbyteorder(self, new_order='S'): return np.ndarray([0, 0])
        def nonzero(self): return (1,)
        def partition(self, kth, axis=-1, kind='introselect', order=None): return None
        def prod(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0])
        def ptp(self, axis=None, out=None): return np.ndarray([0, 0])
        def put(self, indices, values, mode='raise'): return None
        def ravel(self, order='C'): return np.ndarray([0, 0])
        def repeat(self, repeats, axis=None): return np.ndarray([0, 0])
        def reshape(self, shape, order='C'): return np.ndarray([0, 0])
        def resize(self, new_shape, refcheck=True): return None
        def round(self, decimals=0, out=None): return np.ndarray([0, 0])
        def searchsorted(self, v, side='left', sorter=None): return np.ndarray([0, 0])
        def setfield(self, val, dtype, offset=0): return None
        def setflags(self, write=None, align=None, uic=None): return None
        def sort(self, axis=-1, kind='quicksort', order=None): return None
        def squeeze(self, axis=None): return np.ndarray([0, 0])
        def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0])
        def sum(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0])
        def swapaxes(self, axis1, axis2): return np.ndarray([0, 0])
        def take(self, indices, axis=None, out=None, mode='raise'): return np.ndarray([0, 0])
        def tobytes(self, order='C'): return b''
        def tofile(self, fid, sep="", format="%s"): return None
        def tolist(self, ): return []
        def tostring(self, order='C'): return b''
        def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): return np.ndarray([0, 0])
        def transpose(self, *axes): return np.ndarray([0, 0])
        def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0])
        def view(self, dtype=None, type=None): return np.ndarray([0, 0])
    """
    if numpy_supports_type_hints():
        ndarray += """
        @classmethod
        def __class_getitem__(cls, value):
            return cls
        """
    node = extract_node(ndarray)
    return node.infer(context=context)
Ejemplo n.º 4
0
class NumpyBrainCoreNumericTypesTest(unittest.TestCase):
    """
    Test of all the missing types defined in numerictypes module.
    """

    all_types = [
        "uint16",
        "uint32",
        "uint64",
        "float16",
        "float32",
        "float64",
        "float96",
        "complex64",
        "complex128",
        "complex192",
        "timedelta64",
        "datetime64",
        "unicode_",
        "str_",
        "bool_",
        "bool8",
        "byte",
        "int8",
        "bytes0",
        "bytes_",
        "cdouble",
        "cfloat",
        "character",
        "clongdouble",
        "clongfloat",
        "complexfloating",
        "csingle",
        "double",
        "flexible",
        "floating",
        "half",
        "inexact",
        "int0",
        "longcomplex",
        "longdouble",
        "longfloat",
        "short",
        "signedinteger",
        "single",
        "singlecomplex",
        "str0",
        "ubyte",
        "uint",
        "uint0",
        "uintc",
        "uintp",
        "ulonglong",
        "unsignedinteger",
        "ushort",
        "void0",
    ]

    def _inferred_numpy_attribute(self, attrib):
        node = builder.extract_node(f"""
        import numpy.core.numerictypes as tested_module
        missing_type = tested_module.{attrib:s}""")
        return next(node.value.infer())

    def test_numpy_core_types(self):
        """
        Test that all defined types have ClassDef type.
        """
        for typ in self.all_types:
            with self.subTest(typ=typ):
                inferred = self._inferred_numpy_attribute(typ)
                self.assertIsInstance(inferred, nodes.ClassDef)

    def test_generic_types_have_methods(self):
        """
        Test that all generic derived types have specified methods
        """
        generic_methods = [
            "all",
            "any",
            "argmax",
            "argmin",
            "argsort",
            "astype",
            "base",
            "byteswap",
            "choose",
            "clip",
            "compress",
            "conj",
            "conjugate",
            "copy",
            "cumprod",
            "cumsum",
            "data",
            "diagonal",
            "dtype",
            "dump",
            "dumps",
            "fill",
            "flags",
            "flat",
            "flatten",
            "getfield",
            "imag",
            "item",
            "itemset",
            "itemsize",
            "max",
            "mean",
            "min",
            "nbytes",
            "ndim",
            "newbyteorder",
            "nonzero",
            "prod",
            "ptp",
            "put",
            "ravel",
            "real",
            "repeat",
            "reshape",
            "resize",
            "round",
            "searchsorted",
            "setfield",
            "setflags",
            "shape",
            "size",
            "sort",
            "squeeze",
            "std",
            "strides",
            "sum",
            "swapaxes",
            "take",
            "tobytes",
            "tofile",
            "tolist",
            "tostring",
            "trace",
            "transpose",
            "var",
            "view",
        ]

        for type_ in (
                "bool_",
                "bytes_",
                "character",
                "complex128",
                "complex192",
                "complex64",
                "complexfloating",
                "datetime64",
                "flexible",
                "float16",
                "float32",
                "float64",
                "float96",
                "floating",
                "generic",
                "inexact",
                "int16",
                "int32",
                "int32",
                "int64",
                "int8",
                "integer",
                "number",
                "signedinteger",
                "str_",
                "timedelta64",
                "uint16",
                "uint32",
                "uint32",
                "uint64",
                "uint8",
                "unsignedinteger",
                "void",
        ):
            with self.subTest(typ=type_):
                inferred = self._inferred_numpy_attribute(type_)
                for meth in generic_methods:
                    with self.subTest(meth=meth):
                        self.assertTrue(
                            meth in {m.name
                                     for m in inferred.methods()})

    def test_generic_types_have_attributes(self):
        """
        Test that all generic derived types have specified attributes
        """
        generic_attr = [
            "base",
            "data",
            "dtype",
            "flags",
            "flat",
            "imag",
            "itemsize",
            "nbytes",
            "ndim",
            "real",
            "size",
            "strides",
        ]

        for type_ in (
                "bool_",
                "bytes_",
                "character",
                "complex128",
                "complex192",
                "complex64",
                "complexfloating",
                "datetime64",
                "flexible",
                "float16",
                "float32",
                "float64",
                "float96",
                "floating",
                "generic",
                "inexact",
                "int16",
                "int32",
                "int32",
                "int64",
                "int8",
                "integer",
                "number",
                "signedinteger",
                "str_",
                "timedelta64",
                "uint16",
                "uint32",
                "uint32",
                "uint64",
                "uint8",
                "unsignedinteger",
                "void",
        ):
            with self.subTest(typ=type_):
                inferred = self._inferred_numpy_attribute(type_)
                for attr in generic_attr:
                    with self.subTest(attr=attr):
                        self.assertNotEqual(len(inferred.getattr(attr)), 0)

    def test_number_types_have_unary_operators(self):
        """
        Test that number types have unary operators
        """
        unary_ops = ("__neg__", )

        for type_ in (
                "float64",
                "float96",
                "floating",
                "int16",
                "int32",
                "int32",
                "int64",
                "int8",
                "integer",
                "number",
                "signedinteger",
                "uint16",
                "uint32",
                "uint32",
                "uint64",
                "uint8",
                "unsignedinteger",
        ):
            with self.subTest(typ=type_):
                inferred = self._inferred_numpy_attribute(type_)
                for attr in unary_ops:
                    with self.subTest(attr=attr):
                        self.assertNotEqual(len(inferred.getattr(attr)), 0)

    def test_array_types_have_unary_operators(self):
        """
        Test that array types have unary operators
        """
        unary_ops = ("__neg__", "__invert__")

        for type_ in ("ndarray", ):
            with self.subTest(typ=type_):
                inferred = self._inferred_numpy_attribute(type_)
                for attr in unary_ops:
                    with self.subTest(attr=attr):
                        self.assertNotEqual(len(inferred.getattr(attr)), 0)

    def test_datetime_astype_return(self):
        """
        Test that the return of astype method of the datetime object
        is inferred as a ndarray.

        PyCQA/pylint#3332
        """
        node = builder.extract_node("""
        import numpy as np
        import datetime
        test_array = np.datetime64(1, 'us')
        test_array.astype(datetime.datetime)
        """)
        licit_array_types = ".ndarray"
        inferred_values = list(node.infer())
        self.assertTrue(
            len(inferred_values) == 1,
            msg="Too much inferred value for datetime64.astype",
        )
        self.assertTrue(
            inferred_values[-1].pytype() in licit_array_types,
            msg="Illicit type for {:s} ({})".format(
                "datetime64.astype", inferred_values[-1].pytype()),
        )

    @unittest.skipUnless(
        HAS_NUMPY and numpy_supports_type_hints(),
        f"This test requires the numpy library with a version above {NUMPY_VERSION_TYPE_HINTS_SUPPORT}",
    )
    def test_generic_types_are_subscriptables(self):
        """
        Test that all types deriving from generic are subscriptables
        """
        for type_ in (
                "bool_",
                "bytes_",
                "character",
                "complex128",
                "complex192",
                "complex64",
                "complexfloating",
                "datetime64",
                "flexible",
                "float16",
                "float32",
                "float64",
                "float96",
                "floating",
                "generic",
                "inexact",
                "int16",
                "int32",
                "int32",
                "int64",
                "int8",
                "integer",
                "number",
                "signedinteger",
                "str_",
                "timedelta64",
                "uint16",
                "uint32",
                "uint32",
                "uint64",
                "uint8",
                "unsignedinteger",
                "void",
        ):
            with self.subTest(type_=type_):
                src = f"""
                import numpy as np
                np.{type_}[int]
                """
                node = builder.extract_node(src)
                cls_node = node.inferred()[0]
                self.assertIsInstance(cls_node, nodes.ClassDef)
                self.assertEqual(cls_node.name, type_)