numpy 2.4.1__pp311-pypy311_pp73-macosx_14_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- numpy/__config__.py +170 -0
- numpy/__config__.pyi +108 -0
- numpy/__init__.cython-30.pxd +1242 -0
- numpy/__init__.pxd +1155 -0
- numpy/__init__.py +942 -0
- numpy/__init__.pyi +6202 -0
- numpy/_array_api_info.py +346 -0
- numpy/_array_api_info.pyi +206 -0
- numpy/_configtool.py +39 -0
- numpy/_configtool.pyi +1 -0
- numpy/_core/__init__.py +201 -0
- numpy/_core/__init__.pyi +666 -0
- numpy/_core/_add_newdocs.py +7151 -0
- numpy/_core/_add_newdocs.pyi +2 -0
- numpy/_core/_add_newdocs_scalars.py +381 -0
- numpy/_core/_add_newdocs_scalars.pyi +16 -0
- numpy/_core/_asarray.py +130 -0
- numpy/_core/_asarray.pyi +43 -0
- numpy/_core/_dtype.py +366 -0
- numpy/_core/_dtype.pyi +56 -0
- numpy/_core/_dtype_ctypes.py +120 -0
- numpy/_core/_dtype_ctypes.pyi +83 -0
- numpy/_core/_exceptions.py +162 -0
- numpy/_core/_exceptions.pyi +54 -0
- numpy/_core/_internal.py +968 -0
- numpy/_core/_internal.pyi +61 -0
- numpy/_core/_methods.py +252 -0
- numpy/_core/_methods.pyi +22 -0
- numpy/_core/_multiarray_tests.pypy311-pp73-darwin.so +0 -0
- numpy/_core/_multiarray_umath.pypy311-pp73-darwin.so +0 -0
- numpy/_core/_operand_flag_tests.pypy311-pp73-darwin.so +0 -0
- numpy/_core/_rational_tests.pypy311-pp73-darwin.so +0 -0
- numpy/_core/_simd.pyi +35 -0
- numpy/_core/_simd.pypy311-pp73-darwin.so +0 -0
- numpy/_core/_string_helpers.py +100 -0
- numpy/_core/_string_helpers.pyi +12 -0
- numpy/_core/_struct_ufunc_tests.pypy311-pp73-darwin.so +0 -0
- numpy/_core/_type_aliases.py +131 -0
- numpy/_core/_type_aliases.pyi +86 -0
- numpy/_core/_ufunc_config.py +515 -0
- numpy/_core/_ufunc_config.pyi +69 -0
- numpy/_core/_umath_tests.pyi +47 -0
- numpy/_core/_umath_tests.pypy311-pp73-darwin.so +0 -0
- numpy/_core/arrayprint.py +1779 -0
- numpy/_core/arrayprint.pyi +158 -0
- numpy/_core/cversions.py +13 -0
- numpy/_core/defchararray.py +1414 -0
- numpy/_core/defchararray.pyi +1150 -0
- numpy/_core/einsumfunc.py +1650 -0
- numpy/_core/einsumfunc.pyi +184 -0
- numpy/_core/fromnumeric.py +4233 -0
- numpy/_core/fromnumeric.pyi +1735 -0
- numpy/_core/function_base.py +547 -0
- numpy/_core/function_base.pyi +276 -0
- numpy/_core/getlimits.py +462 -0
- numpy/_core/getlimits.pyi +124 -0
- numpy/_core/include/numpy/__multiarray_api.c +376 -0
- numpy/_core/include/numpy/__multiarray_api.h +1628 -0
- numpy/_core/include/numpy/__ufunc_api.c +55 -0
- numpy/_core/include/numpy/__ufunc_api.h +349 -0
- numpy/_core/include/numpy/_neighborhood_iterator_imp.h +90 -0
- numpy/_core/include/numpy/_numpyconfig.h +33 -0
- numpy/_core/include/numpy/_public_dtype_api_table.h +86 -0
- numpy/_core/include/numpy/arrayobject.h +7 -0
- numpy/_core/include/numpy/arrayscalars.h +198 -0
- numpy/_core/include/numpy/dtype_api.h +547 -0
- numpy/_core/include/numpy/halffloat.h +70 -0
- numpy/_core/include/numpy/ndarrayobject.h +304 -0
- numpy/_core/include/numpy/ndarraytypes.h +1982 -0
- numpy/_core/include/numpy/npy_2_compat.h +249 -0
- numpy/_core/include/numpy/npy_2_complexcompat.h +28 -0
- numpy/_core/include/numpy/npy_3kcompat.h +374 -0
- numpy/_core/include/numpy/npy_common.h +989 -0
- numpy/_core/include/numpy/npy_cpu.h +126 -0
- numpy/_core/include/numpy/npy_endian.h +79 -0
- numpy/_core/include/numpy/npy_math.h +602 -0
- numpy/_core/include/numpy/npy_no_deprecated_api.h +20 -0
- numpy/_core/include/numpy/npy_os.h +42 -0
- numpy/_core/include/numpy/numpyconfig.h +185 -0
- numpy/_core/include/numpy/random/LICENSE.txt +21 -0
- numpy/_core/include/numpy/random/bitgen.h +20 -0
- numpy/_core/include/numpy/random/distributions.h +209 -0
- numpy/_core/include/numpy/random/libdivide.h +2079 -0
- numpy/_core/include/numpy/ufuncobject.h +343 -0
- numpy/_core/include/numpy/utils.h +37 -0
- numpy/_core/lib/libnpymath.a +0 -0
- numpy/_core/lib/npy-pkg-config/mlib.ini +12 -0
- numpy/_core/lib/npy-pkg-config/npymath.ini +20 -0
- numpy/_core/lib/pkgconfig/numpy.pc +7 -0
- numpy/_core/memmap.py +363 -0
- numpy/_core/memmap.pyi +3 -0
- numpy/_core/multiarray.py +1740 -0
- numpy/_core/multiarray.pyi +1316 -0
- numpy/_core/numeric.py +2758 -0
- numpy/_core/numeric.pyi +1276 -0
- numpy/_core/numerictypes.py +633 -0
- numpy/_core/numerictypes.pyi +196 -0
- numpy/_core/overrides.py +188 -0
- numpy/_core/overrides.pyi +47 -0
- numpy/_core/printoptions.py +32 -0
- numpy/_core/printoptions.pyi +28 -0
- numpy/_core/records.py +1088 -0
- numpy/_core/records.pyi +340 -0
- numpy/_core/shape_base.py +996 -0
- numpy/_core/shape_base.pyi +182 -0
- numpy/_core/strings.py +1813 -0
- numpy/_core/strings.pyi +536 -0
- numpy/_core/tests/_locales.py +72 -0
- numpy/_core/tests/_natype.py +144 -0
- numpy/_core/tests/data/astype_copy.pkl +0 -0
- numpy/_core/tests/data/generate_umath_validation_data.cpp +170 -0
- numpy/_core/tests/data/recarray_from_file.fits +0 -0
- numpy/_core/tests/data/umath-validation-set-README.txt +15 -0
- numpy/_core/tests/data/umath-validation-set-arccos.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-arccosh.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-arcsin.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-arcsinh.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-arctan.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-arctanh.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-cbrt.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-cos.csv +1375 -0
- numpy/_core/tests/data/umath-validation-set-cosh.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-exp.csv +412 -0
- numpy/_core/tests/data/umath-validation-set-exp2.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-expm1.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-log.csv +271 -0
- numpy/_core/tests/data/umath-validation-set-log10.csv +1629 -0
- numpy/_core/tests/data/umath-validation-set-log1p.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-log2.csv +1629 -0
- numpy/_core/tests/data/umath-validation-set-sin.csv +1370 -0
- numpy/_core/tests/data/umath-validation-set-sinh.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-tan.csv +1429 -0
- numpy/_core/tests/data/umath-validation-set-tanh.csv +1429 -0
- numpy/_core/tests/examples/cython/checks.pyx +373 -0
- numpy/_core/tests/examples/cython/meson.build +43 -0
- numpy/_core/tests/examples/cython/setup.py +39 -0
- numpy/_core/tests/examples/limited_api/limited_api1.c +17 -0
- numpy/_core/tests/examples/limited_api/limited_api2.pyx +11 -0
- numpy/_core/tests/examples/limited_api/limited_api_latest.c +19 -0
- numpy/_core/tests/examples/limited_api/meson.build +59 -0
- numpy/_core/tests/examples/limited_api/setup.py +24 -0
- numpy/_core/tests/test__exceptions.py +90 -0
- numpy/_core/tests/test_abc.py +54 -0
- numpy/_core/tests/test_api.py +655 -0
- numpy/_core/tests/test_argparse.py +90 -0
- numpy/_core/tests/test_array_api_info.py +113 -0
- numpy/_core/tests/test_array_coercion.py +928 -0
- numpy/_core/tests/test_array_interface.py +222 -0
- numpy/_core/tests/test_arraymethod.py +84 -0
- numpy/_core/tests/test_arrayobject.py +75 -0
- numpy/_core/tests/test_arrayprint.py +1324 -0
- numpy/_core/tests/test_casting_floatingpoint_errors.py +154 -0
- numpy/_core/tests/test_casting_unittests.py +955 -0
- numpy/_core/tests/test_conversion_utils.py +209 -0
- numpy/_core/tests/test_cpu_dispatcher.py +48 -0
- numpy/_core/tests/test_cpu_features.py +450 -0
- numpy/_core/tests/test_custom_dtypes.py +393 -0
- numpy/_core/tests/test_cython.py +352 -0
- numpy/_core/tests/test_datetime.py +2792 -0
- numpy/_core/tests/test_defchararray.py +858 -0
- numpy/_core/tests/test_deprecations.py +460 -0
- numpy/_core/tests/test_dlpack.py +190 -0
- numpy/_core/tests/test_dtype.py +2110 -0
- numpy/_core/tests/test_einsum.py +1351 -0
- numpy/_core/tests/test_errstate.py +131 -0
- numpy/_core/tests/test_extint128.py +217 -0
- numpy/_core/tests/test_finfo.py +86 -0
- numpy/_core/tests/test_function_base.py +504 -0
- numpy/_core/tests/test_getlimits.py +171 -0
- numpy/_core/tests/test_half.py +593 -0
- numpy/_core/tests/test_hashtable.py +36 -0
- numpy/_core/tests/test_indexerrors.py +122 -0
- numpy/_core/tests/test_indexing.py +1692 -0
- numpy/_core/tests/test_item_selection.py +167 -0
- numpy/_core/tests/test_limited_api.py +102 -0
- numpy/_core/tests/test_longdouble.py +370 -0
- numpy/_core/tests/test_mem_overlap.py +933 -0
- numpy/_core/tests/test_mem_policy.py +453 -0
- numpy/_core/tests/test_memmap.py +248 -0
- numpy/_core/tests/test_multiarray.py +11008 -0
- numpy/_core/tests/test_multiprocessing.py +55 -0
- numpy/_core/tests/test_multithreading.py +377 -0
- numpy/_core/tests/test_nditer.py +3533 -0
- numpy/_core/tests/test_nep50_promotions.py +287 -0
- numpy/_core/tests/test_numeric.py +4295 -0
- numpy/_core/tests/test_numerictypes.py +650 -0
- numpy/_core/tests/test_overrides.py +800 -0
- numpy/_core/tests/test_print.py +202 -0
- numpy/_core/tests/test_protocols.py +46 -0
- numpy/_core/tests/test_records.py +544 -0
- numpy/_core/tests/test_regression.py +2677 -0
- numpy/_core/tests/test_scalar_ctors.py +203 -0
- numpy/_core/tests/test_scalar_methods.py +328 -0
- numpy/_core/tests/test_scalarbuffer.py +153 -0
- numpy/_core/tests/test_scalarinherit.py +105 -0
- numpy/_core/tests/test_scalarmath.py +1168 -0
- numpy/_core/tests/test_scalarprint.py +403 -0
- numpy/_core/tests/test_shape_base.py +904 -0
- numpy/_core/tests/test_simd.py +1345 -0
- numpy/_core/tests/test_simd_module.py +105 -0
- numpy/_core/tests/test_stringdtype.py +1855 -0
- numpy/_core/tests/test_strings.py +1523 -0
- numpy/_core/tests/test_ufunc.py +3405 -0
- numpy/_core/tests/test_umath.py +4962 -0
- numpy/_core/tests/test_umath_accuracy.py +132 -0
- numpy/_core/tests/test_umath_complex.py +631 -0
- numpy/_core/tests/test_unicode.py +369 -0
- numpy/_core/umath.py +60 -0
- numpy/_core/umath.pyi +232 -0
- numpy/_distributor_init.py +15 -0
- numpy/_distributor_init.pyi +1 -0
- numpy/_expired_attrs_2_0.py +78 -0
- numpy/_expired_attrs_2_0.pyi +61 -0
- numpy/_globals.py +121 -0
- numpy/_globals.pyi +17 -0
- numpy/_pyinstaller/__init__.py +0 -0
- numpy/_pyinstaller/__init__.pyi +0 -0
- numpy/_pyinstaller/hook-numpy.py +36 -0
- numpy/_pyinstaller/hook-numpy.pyi +6 -0
- numpy/_pyinstaller/tests/__init__.py +16 -0
- numpy/_pyinstaller/tests/pyinstaller-smoke.py +32 -0
- numpy/_pyinstaller/tests/test_pyinstaller.py +35 -0
- numpy/_pytesttester.py +201 -0
- numpy/_pytesttester.pyi +18 -0
- numpy/_typing/__init__.py +173 -0
- numpy/_typing/_add_docstring.py +153 -0
- numpy/_typing/_array_like.py +106 -0
- numpy/_typing/_char_codes.py +213 -0
- numpy/_typing/_dtype_like.py +114 -0
- numpy/_typing/_extended_precision.py +15 -0
- numpy/_typing/_nbit.py +19 -0
- numpy/_typing/_nbit_base.py +94 -0
- numpy/_typing/_nbit_base.pyi +39 -0
- numpy/_typing/_nested_sequence.py +79 -0
- numpy/_typing/_scalars.py +20 -0
- numpy/_typing/_shape.py +8 -0
- numpy/_typing/_ufunc.py +7 -0
- numpy/_typing/_ufunc.pyi +975 -0
- numpy/_utils/__init__.py +95 -0
- numpy/_utils/__init__.pyi +28 -0
- numpy/_utils/_convertions.py +18 -0
- numpy/_utils/_convertions.pyi +4 -0
- numpy/_utils/_inspect.py +192 -0
- numpy/_utils/_inspect.pyi +70 -0
- numpy/_utils/_pep440.py +486 -0
- numpy/_utils/_pep440.pyi +118 -0
- numpy/char/__init__.py +2 -0
- numpy/char/__init__.pyi +111 -0
- numpy/conftest.py +248 -0
- numpy/core/__init__.py +33 -0
- numpy/core/__init__.pyi +0 -0
- numpy/core/_dtype.py +10 -0
- numpy/core/_dtype.pyi +0 -0
- numpy/core/_dtype_ctypes.py +10 -0
- numpy/core/_dtype_ctypes.pyi +0 -0
- numpy/core/_internal.py +27 -0
- numpy/core/_multiarray_umath.py +57 -0
- numpy/core/_utils.py +21 -0
- numpy/core/arrayprint.py +10 -0
- numpy/core/defchararray.py +10 -0
- numpy/core/einsumfunc.py +10 -0
- numpy/core/fromnumeric.py +10 -0
- numpy/core/function_base.py +10 -0
- numpy/core/getlimits.py +10 -0
- numpy/core/multiarray.py +25 -0
- numpy/core/numeric.py +12 -0
- numpy/core/numerictypes.py +10 -0
- numpy/core/overrides.py +10 -0
- numpy/core/overrides.pyi +7 -0
- numpy/core/records.py +10 -0
- numpy/core/shape_base.py +10 -0
- numpy/core/umath.py +10 -0
- numpy/ctypeslib/__init__.py +13 -0
- numpy/ctypeslib/__init__.pyi +15 -0
- numpy/ctypeslib/_ctypeslib.py +603 -0
- numpy/ctypeslib/_ctypeslib.pyi +236 -0
- numpy/distutils/__init__.py +64 -0
- numpy/distutils/__init__.pyi +4 -0
- numpy/distutils/__pycache__/conv_template.pypy311.pyc +0 -0
- numpy/distutils/_shell_utils.py +87 -0
- numpy/distutils/armccompiler.py +26 -0
- numpy/distutils/ccompiler.py +826 -0
- numpy/distutils/ccompiler_opt.py +2668 -0
- numpy/distutils/checks/cpu_asimd.c +27 -0
- numpy/distutils/checks/cpu_asimddp.c +16 -0
- numpy/distutils/checks/cpu_asimdfhm.c +19 -0
- numpy/distutils/checks/cpu_asimdhp.c +15 -0
- numpy/distutils/checks/cpu_avx.c +20 -0
- numpy/distutils/checks/cpu_avx2.c +20 -0
- numpy/distutils/checks/cpu_avx512_clx.c +22 -0
- numpy/distutils/checks/cpu_avx512_cnl.c +24 -0
- numpy/distutils/checks/cpu_avx512_icl.c +26 -0
- numpy/distutils/checks/cpu_avx512_knl.c +25 -0
- numpy/distutils/checks/cpu_avx512_knm.c +30 -0
- numpy/distutils/checks/cpu_avx512_skx.c +26 -0
- numpy/distutils/checks/cpu_avx512_spr.c +26 -0
- numpy/distutils/checks/cpu_avx512cd.c +20 -0
- numpy/distutils/checks/cpu_avx512f.c +20 -0
- numpy/distutils/checks/cpu_f16c.c +22 -0
- numpy/distutils/checks/cpu_fma3.c +22 -0
- numpy/distutils/checks/cpu_fma4.c +13 -0
- numpy/distutils/checks/cpu_lsx.c +11 -0
- numpy/distutils/checks/cpu_neon.c +19 -0
- numpy/distutils/checks/cpu_neon_fp16.c +11 -0
- numpy/distutils/checks/cpu_neon_vfpv4.c +21 -0
- numpy/distutils/checks/cpu_popcnt.c +32 -0
- numpy/distutils/checks/cpu_rvv.c +13 -0
- numpy/distutils/checks/cpu_sse.c +20 -0
- numpy/distutils/checks/cpu_sse2.c +20 -0
- numpy/distutils/checks/cpu_sse3.c +20 -0
- numpy/distutils/checks/cpu_sse41.c +20 -0
- numpy/distutils/checks/cpu_sse42.c +20 -0
- numpy/distutils/checks/cpu_ssse3.c +20 -0
- numpy/distutils/checks/cpu_sve.c +14 -0
- numpy/distutils/checks/cpu_vsx.c +21 -0
- numpy/distutils/checks/cpu_vsx2.c +13 -0
- numpy/distutils/checks/cpu_vsx3.c +13 -0
- numpy/distutils/checks/cpu_vsx4.c +14 -0
- numpy/distutils/checks/cpu_vx.c +16 -0
- numpy/distutils/checks/cpu_vxe.c +25 -0
- numpy/distutils/checks/cpu_vxe2.c +21 -0
- numpy/distutils/checks/cpu_xop.c +12 -0
- numpy/distutils/checks/extra_avx512bw_mask.c +18 -0
- numpy/distutils/checks/extra_avx512dq_mask.c +16 -0
- numpy/distutils/checks/extra_avx512f_reduce.c +41 -0
- numpy/distutils/checks/extra_vsx3_half_double.c +12 -0
- numpy/distutils/checks/extra_vsx4_mma.c +21 -0
- numpy/distutils/checks/extra_vsx_asm.c +36 -0
- numpy/distutils/checks/test_flags.c +1 -0
- numpy/distutils/command/__init__.py +41 -0
- numpy/distutils/command/autodist.py +148 -0
- numpy/distutils/command/bdist_rpm.py +22 -0
- numpy/distutils/command/build.py +62 -0
- numpy/distutils/command/build_clib.py +469 -0
- numpy/distutils/command/build_ext.py +752 -0
- numpy/distutils/command/build_py.py +31 -0
- numpy/distutils/command/build_scripts.py +49 -0
- numpy/distutils/command/build_src.py +773 -0
- numpy/distutils/command/config.py +516 -0
- numpy/distutils/command/config_compiler.py +126 -0
- numpy/distutils/command/develop.py +15 -0
- numpy/distutils/command/egg_info.py +25 -0
- numpy/distutils/command/install.py +79 -0
- numpy/distutils/command/install_clib.py +40 -0
- numpy/distutils/command/install_data.py +24 -0
- numpy/distutils/command/install_headers.py +25 -0
- numpy/distutils/command/sdist.py +27 -0
- numpy/distutils/conv_template.py +329 -0
- numpy/distutils/core.py +215 -0
- numpy/distutils/cpuinfo.py +683 -0
- numpy/distutils/exec_command.py +315 -0
- numpy/distutils/extension.py +101 -0
- numpy/distutils/fcompiler/__init__.py +1035 -0
- numpy/distutils/fcompiler/absoft.py +158 -0
- numpy/distutils/fcompiler/arm.py +71 -0
- numpy/distutils/fcompiler/compaq.py +120 -0
- numpy/distutils/fcompiler/environment.py +88 -0
- numpy/distutils/fcompiler/fujitsu.py +46 -0
- numpy/distutils/fcompiler/g95.py +42 -0
- numpy/distutils/fcompiler/gnu.py +555 -0
- numpy/distutils/fcompiler/hpux.py +41 -0
- numpy/distutils/fcompiler/ibm.py +97 -0
- numpy/distutils/fcompiler/intel.py +211 -0
- numpy/distutils/fcompiler/lahey.py +45 -0
- numpy/distutils/fcompiler/mips.py +54 -0
- numpy/distutils/fcompiler/nag.py +87 -0
- numpy/distutils/fcompiler/none.py +28 -0
- numpy/distutils/fcompiler/nv.py +53 -0
- numpy/distutils/fcompiler/pathf95.py +33 -0
- numpy/distutils/fcompiler/pg.py +128 -0
- numpy/distutils/fcompiler/sun.py +51 -0
- numpy/distutils/fcompiler/vast.py +52 -0
- numpy/distutils/from_template.py +261 -0
- numpy/distutils/fujitsuccompiler.py +28 -0
- numpy/distutils/intelccompiler.py +106 -0
- numpy/distutils/lib2def.py +116 -0
- numpy/distutils/line_endings.py +77 -0
- numpy/distutils/log.py +111 -0
- numpy/distutils/mingw/gfortran_vs2003_hack.c +6 -0
- numpy/distutils/mingw32ccompiler.py +620 -0
- numpy/distutils/misc_util.py +2484 -0
- numpy/distutils/msvc9compiler.py +63 -0
- numpy/distutils/msvccompiler.py +76 -0
- numpy/distutils/npy_pkg_config.py +441 -0
- numpy/distutils/numpy_distribution.py +17 -0
- numpy/distutils/pathccompiler.py +21 -0
- numpy/distutils/system_info.py +3267 -0
- numpy/distutils/tests/__init__.py +0 -0
- numpy/distutils/tests/test_build_ext.py +74 -0
- numpy/distutils/tests/test_ccompiler_opt.py +808 -0
- numpy/distutils/tests/test_ccompiler_opt_conf.py +176 -0
- numpy/distutils/tests/test_exec_command.py +217 -0
- numpy/distutils/tests/test_fcompiler.py +43 -0
- numpy/distutils/tests/test_fcompiler_gnu.py +55 -0
- numpy/distutils/tests/test_fcompiler_intel.py +30 -0
- numpy/distutils/tests/test_fcompiler_nagfor.py +22 -0
- numpy/distutils/tests/test_from_template.py +44 -0
- numpy/distutils/tests/test_log.py +34 -0
- numpy/distutils/tests/test_mingw32ccompiler.py +47 -0
- numpy/distutils/tests/test_misc_util.py +88 -0
- numpy/distutils/tests/test_npy_pkg_config.py +84 -0
- numpy/distutils/tests/test_shell_utils.py +79 -0
- numpy/distutils/tests/test_system_info.py +334 -0
- numpy/distutils/tests/utilities.py +90 -0
- numpy/distutils/unixccompiler.py +141 -0
- numpy/doc/ufuncs.py +138 -0
- numpy/dtypes.py +41 -0
- numpy/dtypes.pyi +630 -0
- numpy/exceptions.py +246 -0
- numpy/exceptions.pyi +27 -0
- numpy/f2py/__init__.py +86 -0
- numpy/f2py/__init__.pyi +5 -0
- numpy/f2py/__main__.py +5 -0
- numpy/f2py/__version__.py +1 -0
- numpy/f2py/__version__.pyi +1 -0
- numpy/f2py/_backends/__init__.py +9 -0
- numpy/f2py/_backends/__init__.pyi +5 -0
- numpy/f2py/_backends/_backend.py +44 -0
- numpy/f2py/_backends/_backend.pyi +46 -0
- numpy/f2py/_backends/_distutils.py +76 -0
- numpy/f2py/_backends/_distutils.pyi +13 -0
- numpy/f2py/_backends/_meson.py +244 -0
- numpy/f2py/_backends/_meson.pyi +62 -0
- numpy/f2py/_backends/meson.build.template +58 -0
- numpy/f2py/_isocbind.py +62 -0
- numpy/f2py/_isocbind.pyi +13 -0
- numpy/f2py/_src_pyf.py +247 -0
- numpy/f2py/_src_pyf.pyi +28 -0
- numpy/f2py/auxfuncs.py +1004 -0
- numpy/f2py/auxfuncs.pyi +262 -0
- numpy/f2py/capi_maps.py +811 -0
- numpy/f2py/capi_maps.pyi +33 -0
- numpy/f2py/cb_rules.py +665 -0
- numpy/f2py/cb_rules.pyi +17 -0
- numpy/f2py/cfuncs.py +1563 -0
- numpy/f2py/cfuncs.pyi +31 -0
- numpy/f2py/common_rules.py +143 -0
- numpy/f2py/common_rules.pyi +9 -0
- numpy/f2py/crackfortran.py +3725 -0
- numpy/f2py/crackfortran.pyi +266 -0
- numpy/f2py/diagnose.py +149 -0
- numpy/f2py/diagnose.pyi +1 -0
- numpy/f2py/f2py2e.py +788 -0
- numpy/f2py/f2py2e.pyi +74 -0
- numpy/f2py/f90mod_rules.py +269 -0
- numpy/f2py/f90mod_rules.pyi +16 -0
- numpy/f2py/func2subr.py +329 -0
- numpy/f2py/func2subr.pyi +7 -0
- numpy/f2py/rules.py +1629 -0
- numpy/f2py/rules.pyi +41 -0
- numpy/f2py/setup.cfg +3 -0
- numpy/f2py/src/fortranobject.c +1436 -0
- numpy/f2py/src/fortranobject.h +173 -0
- numpy/f2py/symbolic.py +1518 -0
- numpy/f2py/symbolic.pyi +219 -0
- numpy/f2py/tests/__init__.py +16 -0
- numpy/f2py/tests/src/abstract_interface/foo.f90 +34 -0
- numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90 +6 -0
- numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c +235 -0
- numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap +1 -0
- numpy/f2py/tests/src/assumed_shape/foo_free.f90 +34 -0
- numpy/f2py/tests/src/assumed_shape/foo_mod.f90 +41 -0
- numpy/f2py/tests/src/assumed_shape/foo_use.f90 +19 -0
- numpy/f2py/tests/src/assumed_shape/precision.f90 +4 -0
- numpy/f2py/tests/src/block_docstring/foo.f +6 -0
- numpy/f2py/tests/src/callback/foo.f +62 -0
- numpy/f2py/tests/src/callback/gh17797.f90 +7 -0
- numpy/f2py/tests/src/callback/gh18335.f90 +17 -0
- numpy/f2py/tests/src/callback/gh25211.f +10 -0
- numpy/f2py/tests/src/callback/gh25211.pyf +18 -0
- numpy/f2py/tests/src/callback/gh26681.f90 +18 -0
- numpy/f2py/tests/src/cli/gh_22819.pyf +6 -0
- numpy/f2py/tests/src/cli/hi77.f +3 -0
- numpy/f2py/tests/src/cli/hiworld.f90 +3 -0
- numpy/f2py/tests/src/common/block.f +11 -0
- numpy/f2py/tests/src/common/gh19161.f90 +10 -0
- numpy/f2py/tests/src/crackfortran/accesstype.f90 +13 -0
- numpy/f2py/tests/src/crackfortran/common_with_division.f +17 -0
- numpy/f2py/tests/src/crackfortran/data_common.f +8 -0
- numpy/f2py/tests/src/crackfortran/data_multiplier.f +5 -0
- numpy/f2py/tests/src/crackfortran/data_stmts.f90 +20 -0
- numpy/f2py/tests/src/crackfortran/data_with_comments.f +8 -0
- numpy/f2py/tests/src/crackfortran/foo_deps.f90 +6 -0
- numpy/f2py/tests/src/crackfortran/gh15035.f +16 -0
- numpy/f2py/tests/src/crackfortran/gh17859.f +12 -0
- numpy/f2py/tests/src/crackfortran/gh22648.pyf +7 -0
- numpy/f2py/tests/src/crackfortran/gh23533.f +5 -0
- numpy/f2py/tests/src/crackfortran/gh23598.f90 +4 -0
- numpy/f2py/tests/src/crackfortran/gh23598Warn.f90 +11 -0
- numpy/f2py/tests/src/crackfortran/gh23879.f90 +20 -0
- numpy/f2py/tests/src/crackfortran/gh27697.f90 +12 -0
- numpy/f2py/tests/src/crackfortran/gh2848.f90 +13 -0
- numpy/f2py/tests/src/crackfortran/operators.f90 +49 -0
- numpy/f2py/tests/src/crackfortran/privatemod.f90 +11 -0
- numpy/f2py/tests/src/crackfortran/publicmod.f90 +10 -0
- numpy/f2py/tests/src/crackfortran/pubprivmod.f90 +10 -0
- numpy/f2py/tests/src/crackfortran/unicode_comment.f90 +4 -0
- numpy/f2py/tests/src/f2cmap/.f2py_f2cmap +1 -0
- numpy/f2py/tests/src/f2cmap/isoFortranEnvMap.f90 +9 -0
- numpy/f2py/tests/src/isocintrin/isoCtests.f90 +34 -0
- numpy/f2py/tests/src/kind/foo.f90 +20 -0
- numpy/f2py/tests/src/mixed/foo.f +5 -0
- numpy/f2py/tests/src/mixed/foo_fixed.f90 +8 -0
- numpy/f2py/tests/src/mixed/foo_free.f90 +8 -0
- numpy/f2py/tests/src/modules/gh25337/data.f90 +8 -0
- numpy/f2py/tests/src/modules/gh25337/use_data.f90 +6 -0
- numpy/f2py/tests/src/modules/gh26920/two_mods_with_no_public_entities.f90 +21 -0
- numpy/f2py/tests/src/modules/gh26920/two_mods_with_one_public_routine.f90 +21 -0
- numpy/f2py/tests/src/modules/module_data_docstring.f90 +12 -0
- numpy/f2py/tests/src/modules/use_modules.f90 +20 -0
- numpy/f2py/tests/src/negative_bounds/issue_20853.f90 +7 -0
- numpy/f2py/tests/src/parameter/constant_array.f90 +45 -0
- numpy/f2py/tests/src/parameter/constant_both.f90 +57 -0
- numpy/f2py/tests/src/parameter/constant_compound.f90 +15 -0
- numpy/f2py/tests/src/parameter/constant_integer.f90 +22 -0
- numpy/f2py/tests/src/parameter/constant_non_compound.f90 +23 -0
- numpy/f2py/tests/src/parameter/constant_real.f90 +23 -0
- numpy/f2py/tests/src/quoted_character/foo.f +14 -0
- numpy/f2py/tests/src/regression/AB.inc +1 -0
- numpy/f2py/tests/src/regression/assignOnlyModule.f90 +25 -0
- numpy/f2py/tests/src/regression/datonly.f90 +17 -0
- numpy/f2py/tests/src/regression/f77comments.f +26 -0
- numpy/f2py/tests/src/regression/f77fixedform.f95 +5 -0
- numpy/f2py/tests/src/regression/f90continuation.f90 +9 -0
- numpy/f2py/tests/src/regression/incfile.f90 +5 -0
- numpy/f2py/tests/src/regression/inout.f90 +9 -0
- numpy/f2py/tests/src/regression/lower_f2py_fortran.f90 +5 -0
- numpy/f2py/tests/src/regression/mod_derived_types.f90 +23 -0
- numpy/f2py/tests/src/return_character/foo77.f +45 -0
- numpy/f2py/tests/src/return_character/foo90.f90 +48 -0
- numpy/f2py/tests/src/return_complex/foo77.f +45 -0
- numpy/f2py/tests/src/return_complex/foo90.f90 +48 -0
- numpy/f2py/tests/src/return_integer/foo77.f +56 -0
- numpy/f2py/tests/src/return_integer/foo90.f90 +59 -0
- numpy/f2py/tests/src/return_logical/foo77.f +56 -0
- numpy/f2py/tests/src/return_logical/foo90.f90 +59 -0
- numpy/f2py/tests/src/return_real/foo77.f +45 -0
- numpy/f2py/tests/src/return_real/foo90.f90 +48 -0
- numpy/f2py/tests/src/routines/funcfortranname.f +5 -0
- numpy/f2py/tests/src/routines/funcfortranname.pyf +11 -0
- numpy/f2py/tests/src/routines/subrout.f +4 -0
- numpy/f2py/tests/src/routines/subrout.pyf +10 -0
- numpy/f2py/tests/src/size/foo.f90 +44 -0
- numpy/f2py/tests/src/string/char.f90 +29 -0
- numpy/f2py/tests/src/string/fixed_string.f90 +34 -0
- numpy/f2py/tests/src/string/gh24008.f +8 -0
- numpy/f2py/tests/src/string/gh24662.f90 +7 -0
- numpy/f2py/tests/src/string/gh25286.f90 +14 -0
- numpy/f2py/tests/src/string/gh25286.pyf +12 -0
- numpy/f2py/tests/src/string/gh25286_bc.pyf +12 -0
- numpy/f2py/tests/src/string/scalar_string.f90 +9 -0
- numpy/f2py/tests/src/string/string.f +12 -0
- numpy/f2py/tests/src/value_attrspec/gh21665.f90 +9 -0
- numpy/f2py/tests/test_abstract_interface.py +26 -0
- numpy/f2py/tests/test_array_from_pyobj.py +678 -0
- numpy/f2py/tests/test_assumed_shape.py +50 -0
- numpy/f2py/tests/test_block_docstring.py +20 -0
- numpy/f2py/tests/test_callback.py +263 -0
- numpy/f2py/tests/test_character.py +641 -0
- numpy/f2py/tests/test_common.py +23 -0
- numpy/f2py/tests/test_crackfortran.py +421 -0
- numpy/f2py/tests/test_data.py +71 -0
- numpy/f2py/tests/test_docs.py +66 -0
- numpy/f2py/tests/test_f2cmap.py +17 -0
- numpy/f2py/tests/test_f2py2e.py +983 -0
- numpy/f2py/tests/test_isoc.py +56 -0
- numpy/f2py/tests/test_kind.py +52 -0
- numpy/f2py/tests/test_mixed.py +35 -0
- numpy/f2py/tests/test_modules.py +83 -0
- numpy/f2py/tests/test_parameter.py +129 -0
- numpy/f2py/tests/test_pyf_src.py +43 -0
- numpy/f2py/tests/test_quoted_character.py +18 -0
- numpy/f2py/tests/test_regression.py +187 -0
- numpy/f2py/tests/test_return_character.py +48 -0
- numpy/f2py/tests/test_return_complex.py +67 -0
- numpy/f2py/tests/test_return_integer.py +55 -0
- numpy/f2py/tests/test_return_logical.py +65 -0
- numpy/f2py/tests/test_return_real.py +109 -0
- numpy/f2py/tests/test_routines.py +29 -0
- numpy/f2py/tests/test_semicolon_split.py +75 -0
- numpy/f2py/tests/test_size.py +45 -0
- numpy/f2py/tests/test_string.py +100 -0
- numpy/f2py/tests/test_symbolic.py +500 -0
- numpy/f2py/tests/test_value_attrspec.py +15 -0
- numpy/f2py/tests/util.py +442 -0
- numpy/f2py/use_rules.py +99 -0
- numpy/f2py/use_rules.pyi +9 -0
- numpy/fft/__init__.py +213 -0
- numpy/fft/__init__.pyi +38 -0
- numpy/fft/_helper.py +235 -0
- numpy/fft/_helper.pyi +44 -0
- numpy/fft/_pocketfft.py +1693 -0
- numpy/fft/_pocketfft.pyi +137 -0
- numpy/fft/_pocketfft_umath.pypy311-pp73-darwin.so +0 -0
- numpy/fft/tests/__init__.py +0 -0
- numpy/fft/tests/test_helper.py +167 -0
- numpy/fft/tests/test_pocketfft.py +589 -0
- numpy/lib/__init__.py +97 -0
- numpy/lib/__init__.pyi +52 -0
- numpy/lib/_array_utils_impl.py +62 -0
- numpy/lib/_array_utils_impl.pyi +10 -0
- numpy/lib/_arraypad_impl.py +926 -0
- numpy/lib/_arraypad_impl.pyi +88 -0
- numpy/lib/_arraysetops_impl.py +1158 -0
- numpy/lib/_arraysetops_impl.pyi +462 -0
- numpy/lib/_arrayterator_impl.py +224 -0
- numpy/lib/_arrayterator_impl.pyi +45 -0
- numpy/lib/_datasource.py +700 -0
- numpy/lib/_datasource.pyi +30 -0
- numpy/lib/_format_impl.py +1036 -0
- numpy/lib/_format_impl.pyi +56 -0
- numpy/lib/_function_base_impl.py +5760 -0
- numpy/lib/_function_base_impl.pyi +2324 -0
- numpy/lib/_histograms_impl.py +1085 -0
- numpy/lib/_histograms_impl.pyi +40 -0
- numpy/lib/_index_tricks_impl.py +1048 -0
- numpy/lib/_index_tricks_impl.pyi +267 -0
- numpy/lib/_iotools.py +900 -0
- numpy/lib/_iotools.pyi +116 -0
- numpy/lib/_nanfunctions_impl.py +2006 -0
- numpy/lib/_nanfunctions_impl.pyi +48 -0
- numpy/lib/_npyio_impl.py +2583 -0
- numpy/lib/_npyio_impl.pyi +299 -0
- numpy/lib/_polynomial_impl.py +1465 -0
- numpy/lib/_polynomial_impl.pyi +338 -0
- numpy/lib/_scimath_impl.py +642 -0
- numpy/lib/_scimath_impl.pyi +93 -0
- numpy/lib/_shape_base_impl.py +1289 -0
- numpy/lib/_shape_base_impl.pyi +236 -0
- numpy/lib/_stride_tricks_impl.py +582 -0
- numpy/lib/_stride_tricks_impl.pyi +73 -0
- numpy/lib/_twodim_base_impl.py +1201 -0
- numpy/lib/_twodim_base_impl.pyi +408 -0
- numpy/lib/_type_check_impl.py +710 -0
- numpy/lib/_type_check_impl.pyi +348 -0
- numpy/lib/_ufunclike_impl.py +199 -0
- numpy/lib/_ufunclike_impl.pyi +60 -0
- numpy/lib/_user_array_impl.py +310 -0
- numpy/lib/_user_array_impl.pyi +226 -0
- numpy/lib/_utils_impl.py +784 -0
- numpy/lib/_utils_impl.pyi +22 -0
- numpy/lib/_version.py +153 -0
- numpy/lib/_version.pyi +17 -0
- numpy/lib/array_utils.py +7 -0
- numpy/lib/array_utils.pyi +6 -0
- numpy/lib/format.py +24 -0
- numpy/lib/format.pyi +24 -0
- numpy/lib/introspect.py +94 -0
- numpy/lib/introspect.pyi +3 -0
- numpy/lib/mixins.py +180 -0
- numpy/lib/mixins.pyi +78 -0
- numpy/lib/npyio.py +1 -0
- numpy/lib/npyio.pyi +5 -0
- numpy/lib/recfunctions.py +1681 -0
- numpy/lib/recfunctions.pyi +444 -0
- numpy/lib/scimath.py +13 -0
- numpy/lib/scimath.pyi +12 -0
- numpy/lib/stride_tricks.py +1 -0
- numpy/lib/stride_tricks.pyi +4 -0
- numpy/lib/tests/__init__.py +0 -0
- numpy/lib/tests/data/py2-np0-objarr.npy +0 -0
- numpy/lib/tests/data/py2-objarr.npy +0 -0
- numpy/lib/tests/data/py2-objarr.npz +0 -0
- numpy/lib/tests/data/py3-objarr.npy +0 -0
- numpy/lib/tests/data/py3-objarr.npz +0 -0
- numpy/lib/tests/data/python3.npy +0 -0
- numpy/lib/tests/data/win64python2.npy +0 -0
- numpy/lib/tests/test__datasource.py +328 -0
- numpy/lib/tests/test__iotools.py +358 -0
- numpy/lib/tests/test__version.py +64 -0
- numpy/lib/tests/test_array_utils.py +32 -0
- numpy/lib/tests/test_arraypad.py +1427 -0
- numpy/lib/tests/test_arraysetops.py +1302 -0
- numpy/lib/tests/test_arrayterator.py +45 -0
- numpy/lib/tests/test_format.py +1054 -0
- numpy/lib/tests/test_function_base.py +4750 -0
- numpy/lib/tests/test_histograms.py +855 -0
- numpy/lib/tests/test_index_tricks.py +693 -0
- numpy/lib/tests/test_io.py +2857 -0
- numpy/lib/tests/test_loadtxt.py +1099 -0
- numpy/lib/tests/test_mixins.py +215 -0
- numpy/lib/tests/test_nanfunctions.py +1438 -0
- numpy/lib/tests/test_packbits.py +376 -0
- numpy/lib/tests/test_polynomial.py +325 -0
- numpy/lib/tests/test_recfunctions.py +1042 -0
- numpy/lib/tests/test_regression.py +231 -0
- numpy/lib/tests/test_shape_base.py +813 -0
- numpy/lib/tests/test_stride_tricks.py +655 -0
- numpy/lib/tests/test_twodim_base.py +559 -0
- numpy/lib/tests/test_type_check.py +473 -0
- numpy/lib/tests/test_ufunclike.py +97 -0
- numpy/lib/tests/test_utils.py +80 -0
- numpy/lib/user_array.py +1 -0
- numpy/lib/user_array.pyi +1 -0
- numpy/linalg/__init__.py +95 -0
- numpy/linalg/__init__.pyi +71 -0
- numpy/linalg/_linalg.py +3657 -0
- numpy/linalg/_linalg.pyi +548 -0
- numpy/linalg/_umath_linalg.pyi +60 -0
- numpy/linalg/_umath_linalg.pypy311-pp73-darwin.so +0 -0
- numpy/linalg/lapack_lite.pyi +143 -0
- numpy/linalg/lapack_lite.pypy311-pp73-darwin.so +0 -0
- numpy/linalg/tests/__init__.py +0 -0
- numpy/linalg/tests/test_deprecations.py +21 -0
- numpy/linalg/tests/test_linalg.py +2442 -0
- numpy/linalg/tests/test_regression.py +182 -0
- numpy/ma/API_CHANGES.txt +135 -0
- numpy/ma/LICENSE +24 -0
- numpy/ma/README.rst +236 -0
- numpy/ma/__init__.py +53 -0
- numpy/ma/__init__.pyi +458 -0
- numpy/ma/core.py +8929 -0
- numpy/ma/core.pyi +3720 -0
- numpy/ma/extras.py +2266 -0
- numpy/ma/extras.pyi +297 -0
- numpy/ma/mrecords.py +762 -0
- numpy/ma/mrecords.pyi +96 -0
- numpy/ma/tests/__init__.py +0 -0
- numpy/ma/tests/test_arrayobject.py +40 -0
- numpy/ma/tests/test_core.py +6008 -0
- numpy/ma/tests/test_deprecations.py +65 -0
- numpy/ma/tests/test_extras.py +1945 -0
- numpy/ma/tests/test_mrecords.py +495 -0
- numpy/ma/tests/test_old_ma.py +939 -0
- numpy/ma/tests/test_regression.py +83 -0
- numpy/ma/tests/test_subclassing.py +469 -0
- numpy/ma/testutils.py +294 -0
- numpy/ma/testutils.pyi +69 -0
- numpy/matlib.py +380 -0
- numpy/matlib.pyi +580 -0
- numpy/matrixlib/__init__.py +12 -0
- numpy/matrixlib/__init__.pyi +3 -0
- numpy/matrixlib/defmatrix.py +1119 -0
- numpy/matrixlib/defmatrix.pyi +218 -0
- numpy/matrixlib/tests/__init__.py +0 -0
- numpy/matrixlib/tests/test_defmatrix.py +455 -0
- numpy/matrixlib/tests/test_interaction.py +360 -0
- numpy/matrixlib/tests/test_masked_matrix.py +240 -0
- numpy/matrixlib/tests/test_matrix_linalg.py +110 -0
- numpy/matrixlib/tests/test_multiarray.py +17 -0
- numpy/matrixlib/tests/test_numeric.py +18 -0
- numpy/matrixlib/tests/test_regression.py +31 -0
- numpy/polynomial/__init__.py +187 -0
- numpy/polynomial/__init__.pyi +31 -0
- numpy/polynomial/_polybase.py +1191 -0
- numpy/polynomial/_polybase.pyi +262 -0
- numpy/polynomial/_polytypes.pyi +501 -0
- numpy/polynomial/chebyshev.py +2001 -0
- numpy/polynomial/chebyshev.pyi +180 -0
- numpy/polynomial/hermite.py +1738 -0
- numpy/polynomial/hermite.pyi +106 -0
- numpy/polynomial/hermite_e.py +1640 -0
- numpy/polynomial/hermite_e.pyi +106 -0
- numpy/polynomial/laguerre.py +1673 -0
- numpy/polynomial/laguerre.pyi +100 -0
- numpy/polynomial/legendre.py +1603 -0
- numpy/polynomial/legendre.pyi +100 -0
- numpy/polynomial/polynomial.py +1625 -0
- numpy/polynomial/polynomial.pyi +109 -0
- numpy/polynomial/polyutils.py +759 -0
- numpy/polynomial/polyutils.pyi +307 -0
- numpy/polynomial/tests/__init__.py +0 -0
- numpy/polynomial/tests/test_chebyshev.py +618 -0
- numpy/polynomial/tests/test_classes.py +613 -0
- numpy/polynomial/tests/test_hermite.py +553 -0
- numpy/polynomial/tests/test_hermite_e.py +554 -0
- numpy/polynomial/tests/test_laguerre.py +535 -0
- numpy/polynomial/tests/test_legendre.py +566 -0
- numpy/polynomial/tests/test_polynomial.py +691 -0
- numpy/polynomial/tests/test_polyutils.py +123 -0
- numpy/polynomial/tests/test_printing.py +557 -0
- numpy/polynomial/tests/test_symbol.py +217 -0
- numpy/py.typed +0 -0
- numpy/random/LICENSE.md +71 -0
- numpy/random/__init__.pxd +14 -0
- numpy/random/__init__.py +213 -0
- numpy/random/__init__.pyi +124 -0
- numpy/random/_bounded_integers.pxd +29 -0
- numpy/random/_bounded_integers.pyi +1 -0
- numpy/random/_bounded_integers.pypy311-pp73-darwin.so +0 -0
- numpy/random/_common.pxd +110 -0
- numpy/random/_common.pyi +16 -0
- numpy/random/_common.pypy311-pp73-darwin.so +0 -0
- numpy/random/_examples/cffi/extending.py +44 -0
- numpy/random/_examples/cffi/parse.py +53 -0
- numpy/random/_examples/cython/extending.pyx +77 -0
- numpy/random/_examples/cython/extending_distributions.pyx +117 -0
- numpy/random/_examples/cython/meson.build +53 -0
- numpy/random/_examples/numba/extending.py +86 -0
- numpy/random/_examples/numba/extending_distributions.py +67 -0
- numpy/random/_generator.pyi +862 -0
- numpy/random/_generator.pypy311-pp73-darwin.so +0 -0
- numpy/random/_mt19937.pyi +27 -0
- numpy/random/_mt19937.pypy311-pp73-darwin.so +0 -0
- numpy/random/_pcg64.pyi +41 -0
- numpy/random/_pcg64.pypy311-pp73-darwin.so +0 -0
- numpy/random/_philox.pyi +36 -0
- numpy/random/_philox.pypy311-pp73-darwin.so +0 -0
- numpy/random/_pickle.py +88 -0
- numpy/random/_pickle.pyi +43 -0
- numpy/random/_sfc64.pyi +25 -0
- numpy/random/_sfc64.pypy311-pp73-darwin.so +0 -0
- numpy/random/bit_generator.pxd +40 -0
- numpy/random/bit_generator.pyi +123 -0
- numpy/random/bit_generator.pypy311-pp73-darwin.so +0 -0
- numpy/random/c_distributions.pxd +119 -0
- numpy/random/lib/libnpyrandom.a +0 -0
- numpy/random/mtrand.pyi +759 -0
- numpy/random/mtrand.pypy311-pp73-darwin.so +0 -0
- numpy/random/tests/__init__.py +0 -0
- numpy/random/tests/data/__init__.py +0 -0
- numpy/random/tests/data/generator_pcg64_np121.pkl.gz +0 -0
- numpy/random/tests/data/generator_pcg64_np126.pkl.gz +0 -0
- numpy/random/tests/data/mt19937-testset-1.csv +1001 -0
- numpy/random/tests/data/mt19937-testset-2.csv +1001 -0
- numpy/random/tests/data/pcg64-testset-1.csv +1001 -0
- numpy/random/tests/data/pcg64-testset-2.csv +1001 -0
- numpy/random/tests/data/pcg64dxsm-testset-1.csv +1001 -0
- numpy/random/tests/data/pcg64dxsm-testset-2.csv +1001 -0
- numpy/random/tests/data/philox-testset-1.csv +1001 -0
- numpy/random/tests/data/philox-testset-2.csv +1001 -0
- numpy/random/tests/data/sfc64-testset-1.csv +1001 -0
- numpy/random/tests/data/sfc64-testset-2.csv +1001 -0
- numpy/random/tests/data/sfc64_np126.pkl.gz +0 -0
- numpy/random/tests/test_direct.py +595 -0
- numpy/random/tests/test_extending.py +131 -0
- numpy/random/tests/test_generator_mt19937.py +2825 -0
- numpy/random/tests/test_generator_mt19937_regressions.py +221 -0
- numpy/random/tests/test_random.py +1724 -0
- numpy/random/tests/test_randomstate.py +2099 -0
- numpy/random/tests/test_randomstate_regression.py +213 -0
- numpy/random/tests/test_regression.py +175 -0
- numpy/random/tests/test_seed_sequence.py +79 -0
- numpy/random/tests/test_smoke.py +882 -0
- numpy/rec/__init__.py +2 -0
- numpy/rec/__init__.pyi +23 -0
- numpy/strings/__init__.py +2 -0
- numpy/strings/__init__.pyi +97 -0
- numpy/testing/__init__.py +22 -0
- numpy/testing/__init__.pyi +107 -0
- numpy/testing/_private/__init__.py +0 -0
- numpy/testing/_private/__init__.pyi +0 -0
- numpy/testing/_private/extbuild.py +250 -0
- numpy/testing/_private/extbuild.pyi +25 -0
- numpy/testing/_private/utils.py +2830 -0
- numpy/testing/_private/utils.pyi +505 -0
- numpy/testing/overrides.py +84 -0
- numpy/testing/overrides.pyi +10 -0
- numpy/testing/print_coercion_tables.py +207 -0
- numpy/testing/print_coercion_tables.pyi +26 -0
- numpy/testing/tests/__init__.py +0 -0
- numpy/testing/tests/test_utils.py +2123 -0
- numpy/tests/__init__.py +0 -0
- numpy/tests/test__all__.py +10 -0
- numpy/tests/test_configtool.py +51 -0
- numpy/tests/test_ctypeslib.py +383 -0
- numpy/tests/test_lazyloading.py +42 -0
- numpy/tests/test_matlib.py +59 -0
- numpy/tests/test_numpy_config.py +47 -0
- numpy/tests/test_numpy_version.py +54 -0
- numpy/tests/test_public_api.py +807 -0
- numpy/tests/test_reloading.py +76 -0
- numpy/tests/test_scripts.py +48 -0
- numpy/tests/test_warnings.py +79 -0
- numpy/typing/__init__.py +233 -0
- numpy/typing/__init__.pyi +3 -0
- numpy/typing/mypy_plugin.py +200 -0
- numpy/typing/tests/__init__.py +0 -0
- numpy/typing/tests/data/fail/arithmetic.pyi +126 -0
- numpy/typing/tests/data/fail/array_constructors.pyi +34 -0
- numpy/typing/tests/data/fail/array_like.pyi +15 -0
- numpy/typing/tests/data/fail/array_pad.pyi +6 -0
- numpy/typing/tests/data/fail/arrayprint.pyi +15 -0
- numpy/typing/tests/data/fail/arrayterator.pyi +14 -0
- numpy/typing/tests/data/fail/bitwise_ops.pyi +17 -0
- numpy/typing/tests/data/fail/char.pyi +63 -0
- numpy/typing/tests/data/fail/chararray.pyi +61 -0
- numpy/typing/tests/data/fail/comparisons.pyi +27 -0
- numpy/typing/tests/data/fail/constants.pyi +3 -0
- numpy/typing/tests/data/fail/datasource.pyi +16 -0
- numpy/typing/tests/data/fail/dtype.pyi +17 -0
- numpy/typing/tests/data/fail/einsumfunc.pyi +12 -0
- numpy/typing/tests/data/fail/flatiter.pyi +38 -0
- numpy/typing/tests/data/fail/fromnumeric.pyi +148 -0
- numpy/typing/tests/data/fail/histograms.pyi +12 -0
- numpy/typing/tests/data/fail/index_tricks.pyi +14 -0
- numpy/typing/tests/data/fail/lib_function_base.pyi +60 -0
- numpy/typing/tests/data/fail/lib_polynomial.pyi +29 -0
- numpy/typing/tests/data/fail/lib_utils.pyi +3 -0
- numpy/typing/tests/data/fail/lib_version.pyi +6 -0
- numpy/typing/tests/data/fail/linalg.pyi +52 -0
- numpy/typing/tests/data/fail/ma.pyi +155 -0
- numpy/typing/tests/data/fail/memmap.pyi +5 -0
- numpy/typing/tests/data/fail/modules.pyi +17 -0
- numpy/typing/tests/data/fail/multiarray.pyi +52 -0
- numpy/typing/tests/data/fail/ndarray.pyi +11 -0
- numpy/typing/tests/data/fail/ndarray_misc.pyi +49 -0
- numpy/typing/tests/data/fail/nditer.pyi +8 -0
- numpy/typing/tests/data/fail/nested_sequence.pyi +17 -0
- numpy/typing/tests/data/fail/npyio.pyi +24 -0
- numpy/typing/tests/data/fail/numerictypes.pyi +5 -0
- numpy/typing/tests/data/fail/random.pyi +62 -0
- numpy/typing/tests/data/fail/rec.pyi +17 -0
- numpy/typing/tests/data/fail/scalars.pyi +86 -0
- numpy/typing/tests/data/fail/shape.pyi +7 -0
- numpy/typing/tests/data/fail/shape_base.pyi +8 -0
- numpy/typing/tests/data/fail/stride_tricks.pyi +9 -0
- numpy/typing/tests/data/fail/strings.pyi +52 -0
- numpy/typing/tests/data/fail/testing.pyi +28 -0
- numpy/typing/tests/data/fail/twodim_base.pyi +39 -0
- numpy/typing/tests/data/fail/type_check.pyi +12 -0
- numpy/typing/tests/data/fail/ufunc_config.pyi +21 -0
- numpy/typing/tests/data/fail/ufunclike.pyi +21 -0
- numpy/typing/tests/data/fail/ufuncs.pyi +17 -0
- numpy/typing/tests/data/fail/warnings_and_errors.pyi +5 -0
- numpy/typing/tests/data/misc/extended_precision.pyi +9 -0
- numpy/typing/tests/data/mypy.ini +8 -0
- numpy/typing/tests/data/pass/arithmetic.py +614 -0
- numpy/typing/tests/data/pass/array_constructors.py +138 -0
- numpy/typing/tests/data/pass/array_like.py +43 -0
- numpy/typing/tests/data/pass/arrayprint.py +37 -0
- numpy/typing/tests/data/pass/arrayterator.py +28 -0
- numpy/typing/tests/data/pass/bitwise_ops.py +131 -0
- numpy/typing/tests/data/pass/comparisons.py +316 -0
- numpy/typing/tests/data/pass/dtype.py +57 -0
- numpy/typing/tests/data/pass/einsumfunc.py +36 -0
- numpy/typing/tests/data/pass/flatiter.py +26 -0
- numpy/typing/tests/data/pass/fromnumeric.py +272 -0
- numpy/typing/tests/data/pass/index_tricks.py +62 -0
- numpy/typing/tests/data/pass/lib_user_array.py +22 -0
- numpy/typing/tests/data/pass/lib_utils.py +19 -0
- numpy/typing/tests/data/pass/lib_version.py +18 -0
- numpy/typing/tests/data/pass/literal.py +52 -0
- numpy/typing/tests/data/pass/ma.py +199 -0
- numpy/typing/tests/data/pass/mod.py +149 -0
- numpy/typing/tests/data/pass/modules.py +45 -0
- numpy/typing/tests/data/pass/multiarray.py +77 -0
- numpy/typing/tests/data/pass/ndarray_conversion.py +81 -0
- numpy/typing/tests/data/pass/ndarray_misc.py +199 -0
- numpy/typing/tests/data/pass/ndarray_shape_manipulation.py +47 -0
- numpy/typing/tests/data/pass/nditer.py +4 -0
- numpy/typing/tests/data/pass/numeric.py +90 -0
- numpy/typing/tests/data/pass/numerictypes.py +17 -0
- numpy/typing/tests/data/pass/random.py +1498 -0
- numpy/typing/tests/data/pass/recfunctions.py +164 -0
- numpy/typing/tests/data/pass/scalars.py +249 -0
- numpy/typing/tests/data/pass/shape.py +19 -0
- numpy/typing/tests/data/pass/simple.py +170 -0
- numpy/typing/tests/data/pass/ufunc_config.py +64 -0
- numpy/typing/tests/data/pass/ufunclike.py +52 -0
- numpy/typing/tests/data/pass/ufuncs.py +16 -0
- numpy/typing/tests/data/pass/warnings_and_errors.py +6 -0
- numpy/typing/tests/data/reveal/arithmetic.pyi +719 -0
- numpy/typing/tests/data/reveal/array_api_info.pyi +70 -0
- numpy/typing/tests/data/reveal/array_constructors.pyi +277 -0
- numpy/typing/tests/data/reveal/arraypad.pyi +27 -0
- numpy/typing/tests/data/reveal/arrayprint.pyi +25 -0
- numpy/typing/tests/data/reveal/arraysetops.pyi +74 -0
- numpy/typing/tests/data/reveal/arrayterator.pyi +27 -0
- numpy/typing/tests/data/reveal/bitwise_ops.pyi +166 -0
- numpy/typing/tests/data/reveal/char.pyi +225 -0
- numpy/typing/tests/data/reveal/chararray.pyi +138 -0
- numpy/typing/tests/data/reveal/comparisons.pyi +264 -0
- numpy/typing/tests/data/reveal/constants.pyi +14 -0
- numpy/typing/tests/data/reveal/ctypeslib.pyi +81 -0
- numpy/typing/tests/data/reveal/datasource.pyi +23 -0
- numpy/typing/tests/data/reveal/dtype.pyi +132 -0
- numpy/typing/tests/data/reveal/einsumfunc.pyi +39 -0
- numpy/typing/tests/data/reveal/emath.pyi +54 -0
- numpy/typing/tests/data/reveal/fft.pyi +37 -0
- numpy/typing/tests/data/reveal/flatiter.pyi +86 -0
- numpy/typing/tests/data/reveal/fromnumeric.pyi +347 -0
- numpy/typing/tests/data/reveal/getlimits.pyi +53 -0
- numpy/typing/tests/data/reveal/histograms.pyi +25 -0
- numpy/typing/tests/data/reveal/index_tricks.pyi +70 -0
- numpy/typing/tests/data/reveal/lib_function_base.pyi +409 -0
- numpy/typing/tests/data/reveal/lib_polynomial.pyi +147 -0
- numpy/typing/tests/data/reveal/lib_utils.pyi +17 -0
- numpy/typing/tests/data/reveal/lib_version.pyi +20 -0
- numpy/typing/tests/data/reveal/linalg.pyi +154 -0
- numpy/typing/tests/data/reveal/ma.pyi +1098 -0
- numpy/typing/tests/data/reveal/matrix.pyi +73 -0
- numpy/typing/tests/data/reveal/memmap.pyi +19 -0
- numpy/typing/tests/data/reveal/mod.pyi +178 -0
- numpy/typing/tests/data/reveal/modules.pyi +51 -0
- numpy/typing/tests/data/reveal/multiarray.pyi +197 -0
- numpy/typing/tests/data/reveal/nbit_base_example.pyi +20 -0
- numpy/typing/tests/data/reveal/ndarray_assignability.pyi +82 -0
- numpy/typing/tests/data/reveal/ndarray_conversion.pyi +83 -0
- numpy/typing/tests/data/reveal/ndarray_misc.pyi +246 -0
- numpy/typing/tests/data/reveal/ndarray_shape_manipulation.pyi +47 -0
- numpy/typing/tests/data/reveal/nditer.pyi +49 -0
- numpy/typing/tests/data/reveal/nested_sequence.pyi +25 -0
- numpy/typing/tests/data/reveal/npyio.pyi +83 -0
- numpy/typing/tests/data/reveal/numeric.pyi +170 -0
- numpy/typing/tests/data/reveal/numerictypes.pyi +16 -0
- numpy/typing/tests/data/reveal/polynomial_polybase.pyi +217 -0
- numpy/typing/tests/data/reveal/polynomial_polyutils.pyi +218 -0
- numpy/typing/tests/data/reveal/polynomial_series.pyi +138 -0
- numpy/typing/tests/data/reveal/random.pyi +1546 -0
- numpy/typing/tests/data/reveal/rec.pyi +171 -0
- numpy/typing/tests/data/reveal/scalars.pyi +191 -0
- numpy/typing/tests/data/reveal/shape.pyi +13 -0
- numpy/typing/tests/data/reveal/shape_base.pyi +52 -0
- numpy/typing/tests/data/reveal/stride_tricks.pyi +27 -0
- numpy/typing/tests/data/reveal/strings.pyi +196 -0
- numpy/typing/tests/data/reveal/testing.pyi +198 -0
- numpy/typing/tests/data/reveal/twodim_base.pyi +225 -0
- numpy/typing/tests/data/reveal/type_check.pyi +67 -0
- numpy/typing/tests/data/reveal/ufunc_config.pyi +29 -0
- numpy/typing/tests/data/reveal/ufunclike.pyi +31 -0
- numpy/typing/tests/data/reveal/ufuncs.pyi +142 -0
- numpy/typing/tests/data/reveal/warnings_and_errors.pyi +11 -0
- numpy/typing/tests/test_isfile.py +38 -0
- numpy/typing/tests/test_runtime.py +110 -0
- numpy/typing/tests/test_typing.py +205 -0
- numpy/version.py +11 -0
- numpy/version.pyi +9 -0
- numpy-2.4.1.dist-info/METADATA +139 -0
- numpy-2.4.1.dist-info/RECORD +1039 -0
- numpy-2.4.1.dist-info/WHEEL +6 -0
- numpy-2.4.1.dist-info/entry_points.txt +13 -0
- numpy-2.4.1.dist-info/licenses/LICENSE.txt +935 -0
- numpy-2.4.1.dist-info/licenses/numpy/_core/include/numpy/libdivide/LICENSE.txt +21 -0
- numpy-2.4.1.dist-info/licenses/numpy/_core/src/common/pythoncapi-compat/COPYING +14 -0
- numpy-2.4.1.dist-info/licenses/numpy/_core/src/highway/LICENSE +371 -0
- numpy-2.4.1.dist-info/licenses/numpy/_core/src/multiarray/dragon4_LICENSE.txt +27 -0
- numpy-2.4.1.dist-info/licenses/numpy/_core/src/npysort/x86-simd-sort/LICENSE.md +28 -0
- numpy-2.4.1.dist-info/licenses/numpy/_core/src/umath/svml/LICENSE +30 -0
- numpy-2.4.1.dist-info/licenses/numpy/fft/pocketfft/LICENSE.md +25 -0
- numpy-2.4.1.dist-info/licenses/numpy/linalg/lapack_lite/LICENSE.txt +48 -0
- numpy-2.4.1.dist-info/licenses/numpy/ma/LICENSE +24 -0
- numpy-2.4.1.dist-info/licenses/numpy/random/LICENSE.md +71 -0
- numpy-2.4.1.dist-info/licenses/numpy/random/src/distributions/LICENSE.md +61 -0
- numpy-2.4.1.dist-info/licenses/numpy/random/src/mt19937/LICENSE.md +61 -0
- numpy-2.4.1.dist-info/licenses/numpy/random/src/pcg64/LICENSE.md +22 -0
- numpy-2.4.1.dist-info/licenses/numpy/random/src/philox/LICENSE.md +31 -0
- numpy-2.4.1.dist-info/licenses/numpy/random/src/sfc64/LICENSE.md +27 -0
- numpy-2.4.1.dist-info/licenses/numpy/random/src/splitmix64/LICENSE.md +9 -0
|
@@ -0,0 +1,2110 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
import ctypes
|
|
3
|
+
import gc
|
|
4
|
+
import inspect
|
|
5
|
+
import operator
|
|
6
|
+
import pickle
|
|
7
|
+
import sys
|
|
8
|
+
import types
|
|
9
|
+
from itertools import permutations
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import hypothesis
|
|
13
|
+
import pytest
|
|
14
|
+
from hypothesis.extra import numpy as hynp
|
|
15
|
+
|
|
16
|
+
import numpy as np
|
|
17
|
+
import numpy.dtypes
|
|
18
|
+
from numpy._core._multiarray_tests import create_custom_field_dtype
|
|
19
|
+
from numpy._core._rational_tests import rational
|
|
20
|
+
from numpy.testing import (
|
|
21
|
+
HAS_REFCOUNT,
|
|
22
|
+
IS_64BIT,
|
|
23
|
+
IS_PYPY,
|
|
24
|
+
IS_PYSTON,
|
|
25
|
+
IS_WASM,
|
|
26
|
+
assert_,
|
|
27
|
+
assert_array_equal,
|
|
28
|
+
assert_equal,
|
|
29
|
+
assert_raises,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def assert_dtype_equal(a, b):
|
|
34
|
+
assert_equal(a, b)
|
|
35
|
+
assert_equal(hash(a), hash(b),
|
|
36
|
+
"two equivalent types do not hash to the same value !")
|
|
37
|
+
|
|
38
|
+
def assert_dtype_not_equal(a, b):
|
|
39
|
+
assert_(a != b)
|
|
40
|
+
assert_(hash(a) != hash(b),
|
|
41
|
+
"two different types hash to the same value !")
|
|
42
|
+
|
|
43
|
+
class TestBuiltin:
|
|
44
|
+
@pytest.mark.parametrize('t', [int, float, complex, np.int32, str, object])
|
|
45
|
+
def test_run(self, t):
|
|
46
|
+
"""Only test hash runs at all."""
|
|
47
|
+
dt = np.dtype(t)
|
|
48
|
+
hash(dt)
|
|
49
|
+
|
|
50
|
+
@pytest.mark.parametrize('t', [int, float])
|
|
51
|
+
def test_dtype(self, t):
|
|
52
|
+
# Make sure equivalent byte order char hash the same (e.g. < and = on
|
|
53
|
+
# little endian)
|
|
54
|
+
dt = np.dtype(t)
|
|
55
|
+
dt2 = dt.newbyteorder("<")
|
|
56
|
+
dt3 = dt.newbyteorder(">")
|
|
57
|
+
if dt == dt2:
|
|
58
|
+
assert_(dt.byteorder != dt2.byteorder, "bogus test")
|
|
59
|
+
assert_dtype_equal(dt, dt2)
|
|
60
|
+
else:
|
|
61
|
+
assert_(dt.byteorder != dt3.byteorder, "bogus test")
|
|
62
|
+
assert_dtype_equal(dt, dt3)
|
|
63
|
+
|
|
64
|
+
def test_equivalent_dtype_hashing(self):
|
|
65
|
+
# Make sure equivalent dtypes with different type num hash equal
|
|
66
|
+
uintp = np.dtype(np.uintp)
|
|
67
|
+
if uintp.itemsize == 4:
|
|
68
|
+
left = uintp
|
|
69
|
+
right = np.dtype(np.uint32)
|
|
70
|
+
else:
|
|
71
|
+
left = uintp
|
|
72
|
+
right = np.dtype(np.ulonglong)
|
|
73
|
+
assert_(left == right)
|
|
74
|
+
assert_(hash(left) == hash(right))
|
|
75
|
+
|
|
76
|
+
def test_invalid_types(self):
|
|
77
|
+
# Make sure invalid type strings raise an error
|
|
78
|
+
|
|
79
|
+
assert_raises(TypeError, np.dtype, 'O3')
|
|
80
|
+
assert_raises(TypeError, np.dtype, 'O5')
|
|
81
|
+
assert_raises(TypeError, np.dtype, 'O7')
|
|
82
|
+
assert_raises(TypeError, np.dtype, 'b3')
|
|
83
|
+
assert_raises(TypeError, np.dtype, 'h4')
|
|
84
|
+
assert_raises(TypeError, np.dtype, 'I5')
|
|
85
|
+
assert_raises(TypeError, np.dtype, 'e3')
|
|
86
|
+
assert_raises(TypeError, np.dtype, 'f5')
|
|
87
|
+
|
|
88
|
+
if np.dtype('g').itemsize == 8 or np.dtype('g').itemsize == 16:
|
|
89
|
+
assert_raises(TypeError, np.dtype, 'g12')
|
|
90
|
+
elif np.dtype('g').itemsize == 12:
|
|
91
|
+
assert_raises(TypeError, np.dtype, 'g16')
|
|
92
|
+
|
|
93
|
+
if np.dtype('l').itemsize == 8:
|
|
94
|
+
assert_raises(TypeError, np.dtype, 'l4')
|
|
95
|
+
assert_raises(TypeError, np.dtype, 'L4')
|
|
96
|
+
else:
|
|
97
|
+
assert_raises(TypeError, np.dtype, 'l8')
|
|
98
|
+
assert_raises(TypeError, np.dtype, 'L8')
|
|
99
|
+
|
|
100
|
+
if np.dtype('q').itemsize == 8:
|
|
101
|
+
assert_raises(TypeError, np.dtype, 'q4')
|
|
102
|
+
assert_raises(TypeError, np.dtype, 'Q4')
|
|
103
|
+
else:
|
|
104
|
+
assert_raises(TypeError, np.dtype, 'q8')
|
|
105
|
+
assert_raises(TypeError, np.dtype, 'Q8')
|
|
106
|
+
|
|
107
|
+
# Make sure negative-sized dtype raises an error
|
|
108
|
+
assert_raises(TypeError, np.dtype, 'S-1')
|
|
109
|
+
assert_raises(TypeError, np.dtype, 'U-1')
|
|
110
|
+
assert_raises(TypeError, np.dtype, 'V-1')
|
|
111
|
+
|
|
112
|
+
def test_richcompare_invalid_dtype_equality(self):
|
|
113
|
+
# Make sure objects that cannot be converted to valid
|
|
114
|
+
# dtypes results in False/True when compared to valid dtypes.
|
|
115
|
+
# Here 7 cannot be converted to dtype. No exceptions should be raised
|
|
116
|
+
|
|
117
|
+
assert not np.dtype(np.int32) == 7, "dtype richcompare failed for =="
|
|
118
|
+
assert np.dtype(np.int32) != 7, "dtype richcompare failed for !="
|
|
119
|
+
|
|
120
|
+
@pytest.mark.parametrize(
|
|
121
|
+
'operation',
|
|
122
|
+
[operator.le, operator.lt, operator.ge, operator.gt])
|
|
123
|
+
def test_richcompare_invalid_dtype_comparison(self, operation):
|
|
124
|
+
# Make sure TypeError is raised for comparison operators
|
|
125
|
+
# for invalid dtypes. Here 7 is an invalid dtype.
|
|
126
|
+
|
|
127
|
+
with pytest.raises(TypeError):
|
|
128
|
+
operation(np.dtype(np.int32), 7)
|
|
129
|
+
|
|
130
|
+
@pytest.mark.parametrize("dtype",
|
|
131
|
+
['Bool', 'Bytes0', 'Complex32', 'Complex64',
|
|
132
|
+
'Datetime64', 'Float16', 'Float32', 'Float64',
|
|
133
|
+
'Int8', 'Int16', 'Int32', 'Int64',
|
|
134
|
+
'Object0', 'Str0', 'Timedelta64',
|
|
135
|
+
'UInt8', 'UInt16', 'Uint32', 'UInt32',
|
|
136
|
+
'Uint64', 'UInt64', 'Void0',
|
|
137
|
+
"Float128", "Complex128"])
|
|
138
|
+
def test_numeric_style_types_are_invalid(self, dtype):
|
|
139
|
+
with assert_raises(TypeError):
|
|
140
|
+
np.dtype(dtype)
|
|
141
|
+
|
|
142
|
+
def test_expired_dtypes_with_bad_bytesize(self):
|
|
143
|
+
match: str = r".*removed in NumPy 2.0.*"
|
|
144
|
+
with pytest.raises(TypeError, match=match):
|
|
145
|
+
np.dtype("int0")
|
|
146
|
+
with pytest.raises(TypeError, match=match):
|
|
147
|
+
np.dtype("uint0")
|
|
148
|
+
with pytest.raises(TypeError, match=match):
|
|
149
|
+
np.dtype("bool8")
|
|
150
|
+
with pytest.raises(TypeError, match=match):
|
|
151
|
+
np.dtype("bytes0")
|
|
152
|
+
with pytest.raises(TypeError, match=match):
|
|
153
|
+
np.dtype("str0")
|
|
154
|
+
with pytest.raises(TypeError, match=match):
|
|
155
|
+
np.dtype("object0")
|
|
156
|
+
with pytest.raises(TypeError, match=match):
|
|
157
|
+
np.dtype("void0")
|
|
158
|
+
|
|
159
|
+
@pytest.mark.parametrize(
|
|
160
|
+
'value',
|
|
161
|
+
['m8', 'M8', 'datetime64', 'timedelta64',
|
|
162
|
+
'i4, (2,3)f8, f4', 'S3, 3u8, (3,4)S10',
|
|
163
|
+
'>f', '<f', '=f', '|f',
|
|
164
|
+
])
|
|
165
|
+
def test_dtype_bytes_str_equivalence(self, value):
|
|
166
|
+
bytes_value = value.encode('ascii')
|
|
167
|
+
from_bytes = np.dtype(bytes_value)
|
|
168
|
+
from_str = np.dtype(value)
|
|
169
|
+
assert_dtype_equal(from_bytes, from_str)
|
|
170
|
+
|
|
171
|
+
def test_dtype_from_bytes(self):
|
|
172
|
+
# Empty bytes object
|
|
173
|
+
assert_raises(TypeError, np.dtype, b'')
|
|
174
|
+
# Byte order indicator, but no type
|
|
175
|
+
assert_raises(TypeError, np.dtype, b'|')
|
|
176
|
+
|
|
177
|
+
# Single character with ordinal < NPY_NTYPES_LEGACY returns
|
|
178
|
+
# type by index into _builtin_descrs
|
|
179
|
+
assert_dtype_equal(np.dtype(bytes([0])), np.dtype('bool'))
|
|
180
|
+
assert_dtype_equal(np.dtype(bytes([17])), np.dtype(object))
|
|
181
|
+
|
|
182
|
+
# Single character where value is a valid type code
|
|
183
|
+
assert_dtype_equal(np.dtype(b'f'), np.dtype('float32'))
|
|
184
|
+
|
|
185
|
+
# Bytes with non-ascii values raise errors
|
|
186
|
+
assert_raises(TypeError, np.dtype, b'\xff')
|
|
187
|
+
assert_raises(TypeError, np.dtype, b's\xff')
|
|
188
|
+
|
|
189
|
+
def test_bad_param(self):
|
|
190
|
+
# Can't give a size that's too small
|
|
191
|
+
assert_raises(ValueError, np.dtype,
|
|
192
|
+
{'names': ['f0', 'f1'],
|
|
193
|
+
'formats': ['i4', 'i1'],
|
|
194
|
+
'offsets': [0, 4],
|
|
195
|
+
'itemsize': 4})
|
|
196
|
+
# If alignment is enabled, the alignment (4) must divide the itemsize
|
|
197
|
+
assert_raises(ValueError, np.dtype,
|
|
198
|
+
{'names': ['f0', 'f1'],
|
|
199
|
+
'formats': ['i4', 'i1'],
|
|
200
|
+
'offsets': [0, 4],
|
|
201
|
+
'itemsize': 9}, align=True)
|
|
202
|
+
# If alignment is enabled, the individual fields must be aligned
|
|
203
|
+
assert_raises(ValueError, np.dtype,
|
|
204
|
+
{'names': ['f0', 'f1'],
|
|
205
|
+
'formats': ['i1', 'f4'],
|
|
206
|
+
'offsets': [0, 2]}, align=True)
|
|
207
|
+
|
|
208
|
+
def test_field_order_equality(self):
|
|
209
|
+
x = np.dtype({'names': ['A', 'B'],
|
|
210
|
+
'formats': ['i4', 'f4'],
|
|
211
|
+
'offsets': [0, 4]})
|
|
212
|
+
y = np.dtype({'names': ['B', 'A'],
|
|
213
|
+
'formats': ['i4', 'f4'],
|
|
214
|
+
'offsets': [4, 0]})
|
|
215
|
+
assert_equal(x == y, False)
|
|
216
|
+
# This is a safe cast (not equiv) due to the different names:
|
|
217
|
+
assert np.can_cast(x, y, casting="safe")
|
|
218
|
+
|
|
219
|
+
@pytest.mark.parametrize(
|
|
220
|
+
["type_char", "char_size", "scalar_type"],
|
|
221
|
+
[["U", 4, np.str_],
|
|
222
|
+
["S", 1, np.bytes_]])
|
|
223
|
+
def test_create_string_dtypes_directly(
|
|
224
|
+
self, type_char, char_size, scalar_type):
|
|
225
|
+
dtype_class = type(np.dtype(type_char))
|
|
226
|
+
|
|
227
|
+
dtype = dtype_class(8)
|
|
228
|
+
assert dtype.type is scalar_type
|
|
229
|
+
assert dtype.itemsize == 8 * char_size
|
|
230
|
+
|
|
231
|
+
def test_create_invalid_string_errors(self):
|
|
232
|
+
one_too_big = np.iinfo(np.intc).max + 1
|
|
233
|
+
with pytest.raises(TypeError):
|
|
234
|
+
type(np.dtype("U"))(one_too_big // 4)
|
|
235
|
+
|
|
236
|
+
with pytest.raises(TypeError):
|
|
237
|
+
# Code coverage for very large numbers:
|
|
238
|
+
type(np.dtype("U"))(np.iinfo(np.intp).max // 4 + 1)
|
|
239
|
+
|
|
240
|
+
if one_too_big < sys.maxsize:
|
|
241
|
+
with pytest.raises(TypeError):
|
|
242
|
+
type(np.dtype("S"))(one_too_big)
|
|
243
|
+
|
|
244
|
+
with pytest.raises(ValueError):
|
|
245
|
+
type(np.dtype("U"))(-1)
|
|
246
|
+
|
|
247
|
+
# OverflowError on 32 bit
|
|
248
|
+
with pytest.raises((TypeError, OverflowError)):
|
|
249
|
+
# see gh-26556
|
|
250
|
+
type(np.dtype("S"))(2**61)
|
|
251
|
+
|
|
252
|
+
with pytest.raises(TypeError):
|
|
253
|
+
np.dtype("S1234hello")
|
|
254
|
+
|
|
255
|
+
def test_leading_zero_parsing(self):
|
|
256
|
+
dt1 = np.dtype('S010')
|
|
257
|
+
dt2 = np.dtype('S10')
|
|
258
|
+
|
|
259
|
+
assert dt1 == dt2
|
|
260
|
+
assert repr(dt1) == "dtype('S10')"
|
|
261
|
+
assert dt1.itemsize == 10
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class TestRecord:
|
|
265
|
+
def test_equivalent_record(self):
|
|
266
|
+
"""Test whether equivalent record dtypes hash the same."""
|
|
267
|
+
a = np.dtype([('yo', int)])
|
|
268
|
+
b = np.dtype([('yo', int)])
|
|
269
|
+
assert_dtype_equal(a, b)
|
|
270
|
+
|
|
271
|
+
def test_different_names(self):
|
|
272
|
+
# In theory, they may hash the same (collision) ?
|
|
273
|
+
a = np.dtype([('yo', int)])
|
|
274
|
+
b = np.dtype([('ye', int)])
|
|
275
|
+
assert_dtype_not_equal(a, b)
|
|
276
|
+
|
|
277
|
+
def test_different_titles(self):
|
|
278
|
+
# In theory, they may hash the same (collision) ?
|
|
279
|
+
a = np.dtype({'names': ['r', 'b'],
|
|
280
|
+
'formats': ['u1', 'u1'],
|
|
281
|
+
'titles': ['Red pixel', 'Blue pixel']})
|
|
282
|
+
b = np.dtype({'names': ['r', 'b'],
|
|
283
|
+
'formats': ['u1', 'u1'],
|
|
284
|
+
'titles': ['RRed pixel', 'Blue pixel']})
|
|
285
|
+
assert_dtype_not_equal(a, b)
|
|
286
|
+
|
|
287
|
+
@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
|
|
288
|
+
def test_refcount_dictionary_setting(self):
|
|
289
|
+
names = ["name1"]
|
|
290
|
+
formats = ["f8"]
|
|
291
|
+
titles = ["t1"]
|
|
292
|
+
offsets = [0]
|
|
293
|
+
d = {"names": names, "formats": formats, "titles": titles, "offsets": offsets}
|
|
294
|
+
refcounts = {k: sys.getrefcount(i) for k, i in d.items()}
|
|
295
|
+
np.dtype(d)
|
|
296
|
+
refcounts_new = {k: sys.getrefcount(i) for k, i in d.items()}
|
|
297
|
+
assert refcounts == refcounts_new
|
|
298
|
+
|
|
299
|
+
def test_mutate(self):
|
|
300
|
+
# Mutating a dtype should reset the cached hash value.
|
|
301
|
+
# NOTE: Mutating should be deprecated, but new API added to replace it.
|
|
302
|
+
a = np.dtype([('yo', int)])
|
|
303
|
+
b = np.dtype([('yo', int)])
|
|
304
|
+
c = np.dtype([('ye', int)])
|
|
305
|
+
assert_dtype_equal(a, b)
|
|
306
|
+
assert_dtype_not_equal(a, c)
|
|
307
|
+
a.names = ['ye']
|
|
308
|
+
assert_dtype_equal(a, c)
|
|
309
|
+
assert_dtype_not_equal(a, b)
|
|
310
|
+
state = b.__reduce__()[2]
|
|
311
|
+
a.__setstate__(state)
|
|
312
|
+
assert_dtype_equal(a, b)
|
|
313
|
+
assert_dtype_not_equal(a, c)
|
|
314
|
+
|
|
315
|
+
def test_init_simple_structured(self):
|
|
316
|
+
dt1 = np.dtype("i, i")
|
|
317
|
+
assert dt1.names == ("f0", "f1")
|
|
318
|
+
|
|
319
|
+
dt2 = np.dtype("i,")
|
|
320
|
+
assert dt2.names == ("f0",)
|
|
321
|
+
|
|
322
|
+
def test_mutate_error(self):
|
|
323
|
+
# NOTE: Mutating should be deprecated, but new API added to replace it.
|
|
324
|
+
a = np.dtype("i,i")
|
|
325
|
+
|
|
326
|
+
with pytest.raises(ValueError, match="must replace all names at once"):
|
|
327
|
+
a.names = ["f0"]
|
|
328
|
+
|
|
329
|
+
with pytest.raises(ValueError, match=".*and not string"):
|
|
330
|
+
a.names = ["f0", b"not a unicode name"]
|
|
331
|
+
|
|
332
|
+
def test_not_lists(self):
|
|
333
|
+
"""Test if an appropriate exception is raised when passing bad values to
|
|
334
|
+
the dtype constructor.
|
|
335
|
+
"""
|
|
336
|
+
assert_raises(TypeError, np.dtype,
|
|
337
|
+
{"names": {'A', 'B'}, "formats": ['f8', 'i4']})
|
|
338
|
+
assert_raises(TypeError, np.dtype,
|
|
339
|
+
{"names": ['A', 'B'], "formats": {'f8', 'i4'}})
|
|
340
|
+
|
|
341
|
+
def test_aligned_size(self):
|
|
342
|
+
# Check that structured dtypes get padded to an aligned size
|
|
343
|
+
dt = np.dtype('i4, i1', align=True)
|
|
344
|
+
assert_equal(dt.itemsize, 8)
|
|
345
|
+
dt = np.dtype([('f0', 'i4'), ('f1', 'i1')], align=True)
|
|
346
|
+
assert_equal(dt.itemsize, 8)
|
|
347
|
+
dt = np.dtype({'names': ['f0', 'f1'],
|
|
348
|
+
'formats': ['i4', 'u1'],
|
|
349
|
+
'offsets': [0, 4]}, align=True)
|
|
350
|
+
assert_equal(dt.itemsize, 8)
|
|
351
|
+
dt = np.dtype({'f0': ('i4', 0), 'f1': ('u1', 4)}, align=True)
|
|
352
|
+
assert_equal(dt.itemsize, 8)
|
|
353
|
+
# Nesting should preserve that alignment
|
|
354
|
+
dt1 = np.dtype([('f0', 'i4'),
|
|
355
|
+
('f1', [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')]),
|
|
356
|
+
('f2', 'i1')], align=True)
|
|
357
|
+
assert_equal(dt1.itemsize, 20)
|
|
358
|
+
dt2 = np.dtype({'names': ['f0', 'f1', 'f2'],
|
|
359
|
+
'formats': ['i4',
|
|
360
|
+
[('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')],
|
|
361
|
+
'i1'],
|
|
362
|
+
'offsets': [0, 4, 16]}, align=True)
|
|
363
|
+
assert_equal(dt2.itemsize, 20)
|
|
364
|
+
dt3 = np.dtype({'f0': ('i4', 0),
|
|
365
|
+
'f1': ([('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')], 4),
|
|
366
|
+
'f2': ('i1', 16)}, align=True)
|
|
367
|
+
assert_equal(dt3.itemsize, 20)
|
|
368
|
+
assert_equal(dt1, dt2)
|
|
369
|
+
assert_equal(dt2, dt3)
|
|
370
|
+
# Nesting should preserve packing
|
|
371
|
+
dt1 = np.dtype([('f0', 'i4'),
|
|
372
|
+
('f1', [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')]),
|
|
373
|
+
('f2', 'i1')], align=False)
|
|
374
|
+
assert_equal(dt1.itemsize, 11)
|
|
375
|
+
dt2 = np.dtype({'names': ['f0', 'f1', 'f2'],
|
|
376
|
+
'formats': ['i4',
|
|
377
|
+
[('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')],
|
|
378
|
+
'i1'],
|
|
379
|
+
'offsets': [0, 4, 10]}, align=False)
|
|
380
|
+
assert_equal(dt2.itemsize, 11)
|
|
381
|
+
dt3 = np.dtype({'f0': ('i4', 0),
|
|
382
|
+
'f1': ([('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')], 4),
|
|
383
|
+
'f2': ('i1', 10)}, align=False)
|
|
384
|
+
assert_equal(dt3.itemsize, 11)
|
|
385
|
+
assert_equal(dt1, dt2)
|
|
386
|
+
assert_equal(dt2, dt3)
|
|
387
|
+
# Array of subtype should preserve alignment
|
|
388
|
+
dt1 = np.dtype([('a', '|i1'),
|
|
389
|
+
('b', [('f0', '<i2'),
|
|
390
|
+
('f1', '<f4')], 2)], align=True)
|
|
391
|
+
assert_equal(dt1.descr, [('a', '|i1'), ('', '|V3'),
|
|
392
|
+
('b', [('f0', '<i2'), ('', '|V2'),
|
|
393
|
+
('f1', '<f4')], (2,))])
|
|
394
|
+
|
|
395
|
+
def test_empty_struct_alignment(self):
|
|
396
|
+
# Empty dtypes should have an alignment of 1
|
|
397
|
+
dt = np.dtype([], align=True)
|
|
398
|
+
assert_equal(dt.alignment, 1)
|
|
399
|
+
dt = np.dtype([('f0', [])], align=True)
|
|
400
|
+
assert_equal(dt.alignment, 1)
|
|
401
|
+
dt = np.dtype({'names': [],
|
|
402
|
+
'formats': [],
|
|
403
|
+
'offsets': []}, align=True)
|
|
404
|
+
assert_equal(dt.alignment, 1)
|
|
405
|
+
dt = np.dtype({'names': ['f0'],
|
|
406
|
+
'formats': [[]],
|
|
407
|
+
'offsets': [0]}, align=True)
|
|
408
|
+
assert_equal(dt.alignment, 1)
|
|
409
|
+
|
|
410
|
+
def test_union_struct(self):
|
|
411
|
+
# Should be able to create union dtypes
|
|
412
|
+
dt = np.dtype({'names': ['f0', 'f1', 'f2'], 'formats': ['<u4', '<u2', '<u2'],
|
|
413
|
+
'offsets': [0, 0, 2]}, align=True)
|
|
414
|
+
assert_equal(dt.itemsize, 4)
|
|
415
|
+
a = np.array([3], dtype='<u4').view(dt)
|
|
416
|
+
a['f1'] = 10
|
|
417
|
+
a['f2'] = 36
|
|
418
|
+
assert_equal(a['f0'], 10 + 36 * 256 * 256)
|
|
419
|
+
# Should be able to specify fields out of order
|
|
420
|
+
dt = np.dtype({'names': ['f0', 'f1', 'f2'], 'formats': ['<u4', '<u2', '<u2'],
|
|
421
|
+
'offsets': [4, 0, 2]}, align=True)
|
|
422
|
+
assert_equal(dt.itemsize, 8)
|
|
423
|
+
# field name should not matter: assignment is by position
|
|
424
|
+
dt2 = np.dtype({'names': ['f2', 'f0', 'f1'],
|
|
425
|
+
'formats': ['<u4', '<u2', '<u2'],
|
|
426
|
+
'offsets': [4, 0, 2]}, align=True)
|
|
427
|
+
vals = [(0, 1, 2), (3, 2**15 - 1, 4)]
|
|
428
|
+
vals2 = [(0, 1, 2), (3, 2**15 - 1, 4)]
|
|
429
|
+
a = np.array(vals, dt)
|
|
430
|
+
b = np.array(vals2, dt2)
|
|
431
|
+
assert_equal(a.astype(dt2), b)
|
|
432
|
+
assert_equal(b.astype(dt), a)
|
|
433
|
+
assert_equal(a.view(dt2), b)
|
|
434
|
+
assert_equal(b.view(dt), a)
|
|
435
|
+
# Should not be able to overlap objects with other types
|
|
436
|
+
assert_raises(TypeError, np.dtype,
|
|
437
|
+
{'names': ['f0', 'f1'],
|
|
438
|
+
'formats': ['O', 'i1'],
|
|
439
|
+
'offsets': [0, 2]})
|
|
440
|
+
assert_raises(TypeError, np.dtype,
|
|
441
|
+
{'names': ['f0', 'f1'],
|
|
442
|
+
'formats': ['i4', 'O'],
|
|
443
|
+
'offsets': [0, 3]})
|
|
444
|
+
assert_raises(TypeError, np.dtype,
|
|
445
|
+
{'names': ['f0', 'f1'],
|
|
446
|
+
'formats': [[('a', 'O')], 'i1'],
|
|
447
|
+
'offsets': [0, 2]})
|
|
448
|
+
assert_raises(TypeError, np.dtype,
|
|
449
|
+
{'names': ['f0', 'f1'],
|
|
450
|
+
'formats': ['i4', [('a', 'O')]],
|
|
451
|
+
'offsets': [0, 3]})
|
|
452
|
+
# Out of order should still be ok, however
|
|
453
|
+
dt = np.dtype({'names': ['f0', 'f1'],
|
|
454
|
+
'formats': ['i1', 'O'],
|
|
455
|
+
'offsets': [np.dtype('intp').itemsize, 0]})
|
|
456
|
+
|
|
457
|
+
@pytest.mark.parametrize(["obj", "dtype", "expected"],
|
|
458
|
+
[([], ("2f4"), np.empty((0, 2), dtype="f4")),
|
|
459
|
+
(3, "(3,)f4", [3, 3, 3]),
|
|
460
|
+
(np.float64(2), "(2,)f4", [2, 2]),
|
|
461
|
+
([((0, 1), (1, 2)), ((2,),)], '(2,2)f4', None),
|
|
462
|
+
(["1", "2"], "2i", None)])
|
|
463
|
+
def test_subarray_list(self, obj, dtype, expected):
|
|
464
|
+
dtype = np.dtype(dtype)
|
|
465
|
+
res = np.array(obj, dtype=dtype)
|
|
466
|
+
|
|
467
|
+
if expected is None:
|
|
468
|
+
# iterate the 1-d list to fill the array
|
|
469
|
+
expected = np.empty(len(obj), dtype=dtype)
|
|
470
|
+
for i in range(len(expected)):
|
|
471
|
+
expected[i] = obj[i]
|
|
472
|
+
|
|
473
|
+
assert_array_equal(res, expected)
|
|
474
|
+
|
|
475
|
+
def test_parenthesized_single_number(self):
|
|
476
|
+
with pytest.raises(TypeError, match="not understood"):
|
|
477
|
+
np.dtype("(2)f4")
|
|
478
|
+
|
|
479
|
+
# Deprecation also tested in
|
|
480
|
+
# test_deprecations.py::TestDeprecatedDTypeParenthesizedRepeatCount
|
|
481
|
+
# Left here to allow easy conversion to an exception check.
|
|
482
|
+
with pytest.warns(DeprecationWarning,
|
|
483
|
+
match="parenthesized single number"):
|
|
484
|
+
np.dtype("(2)f4,")
|
|
485
|
+
|
|
486
|
+
def test_comma_datetime(self):
|
|
487
|
+
dt = np.dtype('M8[D],datetime64[Y],i8')
|
|
488
|
+
assert_equal(dt, np.dtype([('f0', 'M8[D]'),
|
|
489
|
+
('f1', 'datetime64[Y]'),
|
|
490
|
+
('f2', 'i8')]))
|
|
491
|
+
|
|
492
|
+
def test_from_dictproxy(self):
|
|
493
|
+
# Tests for PR #5920
|
|
494
|
+
dt = np.dtype({'names': ['a', 'b'], 'formats': ['i4', 'f4']})
|
|
495
|
+
assert_dtype_equal(dt, np.dtype(dt.fields))
|
|
496
|
+
dt2 = np.dtype((np.void, dt.fields))
|
|
497
|
+
assert_equal(dt2.fields, dt.fields)
|
|
498
|
+
|
|
499
|
+
def test_from_dict_with_zero_width_field(self):
|
|
500
|
+
# Regression test for #6430 / #2196
|
|
501
|
+
dt = np.dtype([('val1', np.float32, (0,)), ('val2', int)])
|
|
502
|
+
dt2 = np.dtype({'names': ['val1', 'val2'],
|
|
503
|
+
'formats': [(np.float32, (0,)), int]})
|
|
504
|
+
|
|
505
|
+
assert_dtype_equal(dt, dt2)
|
|
506
|
+
assert_equal(dt.fields['val1'][0].itemsize, 0)
|
|
507
|
+
assert_equal(dt.itemsize, dt.fields['val2'][0].itemsize)
|
|
508
|
+
|
|
509
|
+
def test_bool_commastring(self):
|
|
510
|
+
d = np.dtype('?,?,?') # raises?
|
|
511
|
+
assert_equal(len(d.names), 3)
|
|
512
|
+
for n in d.names:
|
|
513
|
+
assert_equal(d.fields[n][0], np.dtype('?'))
|
|
514
|
+
|
|
515
|
+
def test_nonint_offsets(self):
|
|
516
|
+
# gh-8059
|
|
517
|
+
def make_dtype(off):
|
|
518
|
+
return np.dtype({'names': ['A'], 'formats': ['i4'],
|
|
519
|
+
'offsets': [off]})
|
|
520
|
+
|
|
521
|
+
assert_raises(TypeError, make_dtype, 'ASD')
|
|
522
|
+
assert_raises(OverflowError, make_dtype, 2**70)
|
|
523
|
+
assert_raises(TypeError, make_dtype, 2.3)
|
|
524
|
+
assert_raises(ValueError, make_dtype, -10)
|
|
525
|
+
|
|
526
|
+
# no errors here:
|
|
527
|
+
dt = make_dtype(np.uint32(0))
|
|
528
|
+
np.zeros(1, dtype=dt)[0].item()
|
|
529
|
+
|
|
530
|
+
def test_fields_by_index(self):
|
|
531
|
+
dt = np.dtype([('a', np.int8), ('b', np.float32, 3)])
|
|
532
|
+
assert_dtype_equal(dt[0], np.dtype(np.int8))
|
|
533
|
+
assert_dtype_equal(dt[1], np.dtype((np.float32, 3)))
|
|
534
|
+
assert_dtype_equal(dt[-1], dt[1])
|
|
535
|
+
assert_dtype_equal(dt[-2], dt[0])
|
|
536
|
+
assert_raises(IndexError, lambda: dt[-3])
|
|
537
|
+
|
|
538
|
+
assert_raises(TypeError, operator.getitem, dt, 3.0)
|
|
539
|
+
|
|
540
|
+
assert_equal(dt[1], dt[np.int8(1)])
|
|
541
|
+
|
|
542
|
+
@pytest.mark.parametrize('align_flag', [False, True])
|
|
543
|
+
def test_multifield_index(self, align_flag):
|
|
544
|
+
# indexing with a list produces subfields
|
|
545
|
+
# the align flag should be preserved
|
|
546
|
+
dt = np.dtype([
|
|
547
|
+
(('title', 'col1'), '<U20'), ('A', '<f8'), ('B', '<f8')
|
|
548
|
+
], align=align_flag)
|
|
549
|
+
|
|
550
|
+
dt_sub = dt[['B', 'col1']]
|
|
551
|
+
assert_equal(
|
|
552
|
+
dt_sub,
|
|
553
|
+
np.dtype({
|
|
554
|
+
'names': ['B', 'col1'],
|
|
555
|
+
'formats': ['<f8', '<U20'],
|
|
556
|
+
'offsets': [88, 0],
|
|
557
|
+
'titles': [None, 'title'],
|
|
558
|
+
'itemsize': 96
|
|
559
|
+
})
|
|
560
|
+
)
|
|
561
|
+
assert_equal(dt_sub.isalignedstruct, align_flag)
|
|
562
|
+
|
|
563
|
+
dt_sub = dt[['B']]
|
|
564
|
+
assert_equal(
|
|
565
|
+
dt_sub,
|
|
566
|
+
np.dtype({
|
|
567
|
+
'names': ['B'],
|
|
568
|
+
'formats': ['<f8'],
|
|
569
|
+
'offsets': [88],
|
|
570
|
+
'itemsize': 96
|
|
571
|
+
})
|
|
572
|
+
)
|
|
573
|
+
assert_equal(dt_sub.isalignedstruct, align_flag)
|
|
574
|
+
|
|
575
|
+
dt_sub = dt[[]]
|
|
576
|
+
assert_equal(
|
|
577
|
+
dt_sub,
|
|
578
|
+
np.dtype({
|
|
579
|
+
'names': [],
|
|
580
|
+
'formats': [],
|
|
581
|
+
'offsets': [],
|
|
582
|
+
'itemsize': 96
|
|
583
|
+
})
|
|
584
|
+
)
|
|
585
|
+
assert_equal(dt_sub.isalignedstruct, align_flag)
|
|
586
|
+
|
|
587
|
+
assert_raises(TypeError, operator.getitem, dt, ())
|
|
588
|
+
assert_raises(TypeError, operator.getitem, dt, [1, 2, 3])
|
|
589
|
+
assert_raises(TypeError, operator.getitem, dt, ['col1', 2])
|
|
590
|
+
assert_raises(KeyError, operator.getitem, dt, ['fake'])
|
|
591
|
+
assert_raises(KeyError, operator.getitem, dt, ['title'])
|
|
592
|
+
assert_raises(ValueError, operator.getitem, dt, ['col1', 'col1'])
|
|
593
|
+
|
|
594
|
+
def test_partial_dict(self):
|
|
595
|
+
# 'names' is missing
|
|
596
|
+
assert_raises(ValueError, np.dtype,
|
|
597
|
+
{'formats': ['i4', 'i4'], 'f0': ('i4', 0), 'f1': ('i4', 4)})
|
|
598
|
+
|
|
599
|
+
def test_fieldless_views(self):
|
|
600
|
+
a = np.zeros(2, dtype={'names': [], 'formats': [], 'offsets': [],
|
|
601
|
+
'itemsize': 8})
|
|
602
|
+
assert_raises(ValueError, a.view, np.dtype([]))
|
|
603
|
+
|
|
604
|
+
d = np.dtype((np.dtype([]), 10))
|
|
605
|
+
assert_equal(d.shape, (10,))
|
|
606
|
+
assert_equal(d.itemsize, 0)
|
|
607
|
+
assert_equal(d.base, np.dtype([]))
|
|
608
|
+
|
|
609
|
+
arr = np.fromiter((() for i in range(10)), [])
|
|
610
|
+
assert_equal(arr.dtype, np.dtype([]))
|
|
611
|
+
assert_raises(ValueError, np.frombuffer, b'', dtype=[])
|
|
612
|
+
assert_equal(np.frombuffer(b'', dtype=[], count=2),
|
|
613
|
+
np.empty(2, dtype=[]))
|
|
614
|
+
|
|
615
|
+
assert_raises(ValueError, np.dtype, ([], 'f8'))
|
|
616
|
+
assert_raises(ValueError, np.zeros(1, dtype='i4').view, [])
|
|
617
|
+
|
|
618
|
+
assert_equal(np.zeros(2, dtype=[]) == np.zeros(2, dtype=[]),
|
|
619
|
+
np.ones(2, dtype=bool))
|
|
620
|
+
|
|
621
|
+
assert_equal(np.zeros((1, 2), dtype=[]) == a,
|
|
622
|
+
np.ones((1, 2), dtype=bool))
|
|
623
|
+
|
|
624
|
+
def test_nonstructured_with_object(self):
|
|
625
|
+
# See gh-23277, the dtype here thinks it contain objects, if the
|
|
626
|
+
# assert about that fails, the test becomes meaningless (which is OK)
|
|
627
|
+
arr = np.recarray((0,), dtype="O")
|
|
628
|
+
assert arr.dtype.names is None # no fields
|
|
629
|
+
assert arr.dtype.hasobject # but claims to contain objects
|
|
630
|
+
del arr # the deletion failed previously.
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
class TestSubarray:
|
|
634
|
+
def test_single_subarray(self):
|
|
635
|
+
a = np.dtype((int, (2)))
|
|
636
|
+
b = np.dtype((int, (2,)))
|
|
637
|
+
assert_dtype_equal(a, b)
|
|
638
|
+
|
|
639
|
+
assert_equal(type(a.subdtype[1]), tuple)
|
|
640
|
+
assert_equal(type(b.subdtype[1]), tuple)
|
|
641
|
+
|
|
642
|
+
def test_equivalent_record(self):
|
|
643
|
+
"""Test whether equivalent subarray dtypes hash the same."""
|
|
644
|
+
a = np.dtype((int, (2, 3)))
|
|
645
|
+
b = np.dtype((int, (2, 3)))
|
|
646
|
+
assert_dtype_equal(a, b)
|
|
647
|
+
|
|
648
|
+
def test_nonequivalent_record(self):
|
|
649
|
+
"""Test whether different subarray dtypes hash differently."""
|
|
650
|
+
a = np.dtype((int, (2, 3)))
|
|
651
|
+
b = np.dtype((int, (3, 2)))
|
|
652
|
+
assert_dtype_not_equal(a, b)
|
|
653
|
+
|
|
654
|
+
a = np.dtype((int, (2, 3)))
|
|
655
|
+
b = np.dtype((int, (2, 2)))
|
|
656
|
+
assert_dtype_not_equal(a, b)
|
|
657
|
+
|
|
658
|
+
a = np.dtype((int, (1, 2, 3)))
|
|
659
|
+
b = np.dtype((int, (1, 2)))
|
|
660
|
+
assert_dtype_not_equal(a, b)
|
|
661
|
+
|
|
662
|
+
def test_shape_equal(self):
|
|
663
|
+
"""Test some data types that are equal"""
|
|
664
|
+
assert_dtype_equal(np.dtype('f8'), np.dtype(('f8', ())))
|
|
665
|
+
assert_dtype_equal(np.dtype('(1,)f8'), np.dtype(('f8', 1)))
|
|
666
|
+
assert np.dtype(('f8', 1)).shape == (1,)
|
|
667
|
+
assert_dtype_equal(np.dtype((int, 2)), np.dtype((int, (2,))))
|
|
668
|
+
assert_dtype_equal(np.dtype(('<f4', (3, 2))), np.dtype(('<f4', (3, 2))))
|
|
669
|
+
d = ([('a', 'f4', (1, 2)), ('b', 'f8', (3, 1))], (3, 2))
|
|
670
|
+
assert_dtype_equal(np.dtype(d), np.dtype(d))
|
|
671
|
+
|
|
672
|
+
def test_shape_simple(self):
|
|
673
|
+
"""Test some simple cases that shouldn't be equal"""
|
|
674
|
+
assert_dtype_not_equal(np.dtype('f8'), np.dtype(('f8', (1,))))
|
|
675
|
+
assert_dtype_not_equal(np.dtype(('f8', (1,))), np.dtype(('f8', (1, 1))))
|
|
676
|
+
assert_dtype_not_equal(np.dtype(('f4', (3, 2))), np.dtype(('f4', (2, 3))))
|
|
677
|
+
|
|
678
|
+
def test_shape_monster(self):
|
|
679
|
+
"""Test some more complicated cases that shouldn't be equal"""
|
|
680
|
+
assert_dtype_not_equal(
|
|
681
|
+
np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
|
|
682
|
+
np.dtype(([('a', 'f4', (1, 2)), ('b', 'f8', (1, 3))], (2, 2))))
|
|
683
|
+
assert_dtype_not_equal(
|
|
684
|
+
np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
|
|
685
|
+
np.dtype(([('a', 'f4', (2, 1)), ('b', 'i8', (1, 3))], (2, 2))))
|
|
686
|
+
assert_dtype_not_equal(
|
|
687
|
+
np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
|
|
688
|
+
np.dtype(([('e', 'f8', (1, 3)), ('d', 'f4', (2, 1))], (2, 2))))
|
|
689
|
+
assert_dtype_not_equal(
|
|
690
|
+
np.dtype(([('a', [('a', 'i4', 6)], (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
|
|
691
|
+
np.dtype(([('a', [('a', 'u4', 6)], (2, 1)), ('b', 'f8', (1, 3))], (2, 2))))
|
|
692
|
+
|
|
693
|
+
def test_shape_sequence(self):
|
|
694
|
+
# Any sequence of integers should work as shape, but the result
|
|
695
|
+
# should be a tuple (immutable) of base type integers.
|
|
696
|
+
a = np.array([1, 2, 3], dtype=np.int16)
|
|
697
|
+
l = [1, 2, 3]
|
|
698
|
+
# Array gets converted
|
|
699
|
+
dt = np.dtype([('a', 'f4', a)])
|
|
700
|
+
assert_(isinstance(dt['a'].shape, tuple))
|
|
701
|
+
assert_(isinstance(dt['a'].shape[0], int))
|
|
702
|
+
# List gets converted
|
|
703
|
+
dt = np.dtype([('a', 'f4', l)])
|
|
704
|
+
assert_(isinstance(dt['a'].shape, tuple))
|
|
705
|
+
#
|
|
706
|
+
|
|
707
|
+
class IntLike:
|
|
708
|
+
def __index__(self):
|
|
709
|
+
return 3
|
|
710
|
+
|
|
711
|
+
def __int__(self):
|
|
712
|
+
# (a PyNumber_Check fails without __int__)
|
|
713
|
+
return 3
|
|
714
|
+
|
|
715
|
+
dt = np.dtype([('a', 'f4', IntLike())])
|
|
716
|
+
assert_(isinstance(dt['a'].shape, tuple))
|
|
717
|
+
assert_(isinstance(dt['a'].shape[0], int))
|
|
718
|
+
dt = np.dtype([('a', 'f4', (IntLike(),))])
|
|
719
|
+
assert_(isinstance(dt['a'].shape, tuple))
|
|
720
|
+
assert_(isinstance(dt['a'].shape[0], int))
|
|
721
|
+
|
|
722
|
+
def test_shape_matches_ndim(self):
|
|
723
|
+
dt = np.dtype([('a', 'f4', ())])
|
|
724
|
+
assert_equal(dt['a'].shape, ())
|
|
725
|
+
assert_equal(dt['a'].ndim, 0)
|
|
726
|
+
|
|
727
|
+
dt = np.dtype([('a', 'f4')])
|
|
728
|
+
assert_equal(dt['a'].shape, ())
|
|
729
|
+
assert_equal(dt['a'].ndim, 0)
|
|
730
|
+
|
|
731
|
+
dt = np.dtype([('a', 'f4', 4)])
|
|
732
|
+
assert_equal(dt['a'].shape, (4,))
|
|
733
|
+
assert_equal(dt['a'].ndim, 1)
|
|
734
|
+
|
|
735
|
+
dt = np.dtype([('a', 'f4', (1, 2, 3))])
|
|
736
|
+
assert_equal(dt['a'].shape, (1, 2, 3))
|
|
737
|
+
assert_equal(dt['a'].ndim, 3)
|
|
738
|
+
|
|
739
|
+
def test_shape_invalid(self):
|
|
740
|
+
# Check that the shape is valid.
|
|
741
|
+
max_int = np.iinfo(np.intc).max
|
|
742
|
+
max_intp = np.iinfo(np.intp).max
|
|
743
|
+
# Too large values (the datatype is part of this)
|
|
744
|
+
assert_raises(ValueError, np.dtype, [('a', 'f4', max_int // 4 + 1)])
|
|
745
|
+
assert_raises(ValueError, np.dtype, [('a', 'f4', max_int + 1)])
|
|
746
|
+
assert_raises(ValueError, np.dtype, [('a', 'f4', (max_int, 2))])
|
|
747
|
+
# Takes a different code path (fails earlier:
|
|
748
|
+
assert_raises(ValueError, np.dtype, [('a', 'f4', max_intp + 1)])
|
|
749
|
+
# Negative values
|
|
750
|
+
assert_raises(ValueError, np.dtype, [('a', 'f4', -1)])
|
|
751
|
+
assert_raises(ValueError, np.dtype, [('a', 'f4', (-1, -1))])
|
|
752
|
+
|
|
753
|
+
def test_alignment(self):
|
|
754
|
+
# Check that subarrays are aligned
|
|
755
|
+
t1 = np.dtype('(1,)i4', align=True)
|
|
756
|
+
t2 = np.dtype('2i4', align=True)
|
|
757
|
+
assert_equal(t1.alignment, t2.alignment)
|
|
758
|
+
|
|
759
|
+
def test_aligned_empty(self):
|
|
760
|
+
# Mainly regression test for gh-19696: construction failed completely
|
|
761
|
+
dt = np.dtype([], align=True)
|
|
762
|
+
assert dt == np.dtype([])
|
|
763
|
+
dt = np.dtype({"names": [], "formats": [], "itemsize": 0}, align=True)
|
|
764
|
+
assert dt == np.dtype([])
|
|
765
|
+
|
|
766
|
+
def test_subarray_base_item(self):
|
|
767
|
+
arr = np.ones(3, dtype=[("f", "i", 3)])
|
|
768
|
+
# Extracting the field "absorbs" the subarray into a view:
|
|
769
|
+
assert arr["f"].base is arr
|
|
770
|
+
# Extract the structured item, and then check the tuple component:
|
|
771
|
+
item = arr.item(0)
|
|
772
|
+
assert type(item) is tuple and len(item) == 1
|
|
773
|
+
assert item[0].base is arr
|
|
774
|
+
|
|
775
|
+
def test_subarray_cast_copies(self):
|
|
776
|
+
# Older versions of NumPy did NOT copy, but they got the ownership
|
|
777
|
+
# wrong (not actually knowing the correct base!). Versions since 1.21
|
|
778
|
+
# (I think) crashed fairly reliable. This defines the correct behavior
|
|
779
|
+
# as a copy. Keeping the ownership would be possible (but harder)
|
|
780
|
+
arr = np.ones(3, dtype=[("f", "i", 3)])
|
|
781
|
+
cast = arr.astype(object)
|
|
782
|
+
for fields in cast:
|
|
783
|
+
assert type(fields) == tuple and len(fields) == 1
|
|
784
|
+
subarr = fields[0]
|
|
785
|
+
assert subarr.base is None
|
|
786
|
+
assert subarr.flags.owndata
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
def iter_struct_object_dtypes():
|
|
790
|
+
"""
|
|
791
|
+
Iterates over a few complex dtypes and object pattern which
|
|
792
|
+
fill the array with a given object (defaults to a singleton).
|
|
793
|
+
|
|
794
|
+
Yields
|
|
795
|
+
------
|
|
796
|
+
dtype : dtype
|
|
797
|
+
pattern : tuple
|
|
798
|
+
Structured tuple for use with `np.array`.
|
|
799
|
+
count : int
|
|
800
|
+
Number of objects stored in the dtype.
|
|
801
|
+
singleton : object
|
|
802
|
+
A singleton object. The returned pattern is constructed so that
|
|
803
|
+
all objects inside the datatype are set to the singleton.
|
|
804
|
+
"""
|
|
805
|
+
obj = object()
|
|
806
|
+
|
|
807
|
+
dt = np.dtype([('b', 'O', (2, 3))])
|
|
808
|
+
p = ([[obj] * 3] * 2,)
|
|
809
|
+
yield pytest.param(dt, p, 6, obj, id="<subarray>")
|
|
810
|
+
|
|
811
|
+
dt = np.dtype([('a', 'i4'), ('b', 'O', (2, 3))])
|
|
812
|
+
p = (0, [[obj] * 3] * 2)
|
|
813
|
+
yield pytest.param(dt, p, 6, obj, id="<subarray in field>")
|
|
814
|
+
|
|
815
|
+
dt = np.dtype([('a', 'i4'),
|
|
816
|
+
('b', [('ba', 'O'), ('bb', 'i1')], (2, 3))])
|
|
817
|
+
p = (0, [[(obj, 0)] * 3] * 2)
|
|
818
|
+
yield pytest.param(dt, p, 6, obj, id="<structured subarray 1>")
|
|
819
|
+
|
|
820
|
+
dt = np.dtype([('a', 'i4'),
|
|
821
|
+
('b', [('ba', 'O'), ('bb', 'O')], (2, 3))])
|
|
822
|
+
p = (0, [[(obj, obj)] * 3] * 2)
|
|
823
|
+
yield pytest.param(dt, p, 12, obj, id="<structured subarray 2>")
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
@pytest.mark.skipif(
|
|
827
|
+
sys.version_info >= (3, 12),
|
|
828
|
+
reason="Python 3.12 has immortal refcounts, this test will no longer "
|
|
829
|
+
"work. See gh-23986"
|
|
830
|
+
)
|
|
831
|
+
@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
|
|
832
|
+
class TestStructuredObjectRefcounting:
|
|
833
|
+
"""These tests cover various uses of complicated structured types which
|
|
834
|
+
include objects and thus require reference counting.
|
|
835
|
+
"""
|
|
836
|
+
@pytest.mark.parametrize(['dt', 'pat', 'count', 'singleton'],
|
|
837
|
+
iter_struct_object_dtypes())
|
|
838
|
+
@pytest.mark.parametrize(["creation_func", "creation_obj"], [
|
|
839
|
+
pytest.param(np.empty, None,
|
|
840
|
+
# None is probably used for too many things
|
|
841
|
+
marks=pytest.mark.skip("unreliable due to python's behaviour")),
|
|
842
|
+
(np.ones, 1),
|
|
843
|
+
(np.zeros, 0)])
|
|
844
|
+
def test_structured_object_create_delete(self, dt, pat, count, singleton,
|
|
845
|
+
creation_func, creation_obj):
|
|
846
|
+
"""Structured object reference counting in creation and deletion"""
|
|
847
|
+
# The test assumes that 0, 1, and None are singletons.
|
|
848
|
+
gc.collect()
|
|
849
|
+
before = sys.getrefcount(creation_obj)
|
|
850
|
+
arr = creation_func(3, dt)
|
|
851
|
+
|
|
852
|
+
now = sys.getrefcount(creation_obj)
|
|
853
|
+
assert now - before == count * 3
|
|
854
|
+
del arr
|
|
855
|
+
now = sys.getrefcount(creation_obj)
|
|
856
|
+
assert now == before
|
|
857
|
+
|
|
858
|
+
@pytest.mark.parametrize(['dt', 'pat', 'count', 'singleton'],
|
|
859
|
+
iter_struct_object_dtypes())
|
|
860
|
+
def test_structured_object_item_setting(self, dt, pat, count, singleton):
|
|
861
|
+
"""Structured object reference counting for simple item setting"""
|
|
862
|
+
one = 1
|
|
863
|
+
|
|
864
|
+
gc.collect()
|
|
865
|
+
before = sys.getrefcount(singleton)
|
|
866
|
+
arr = np.array([pat] * 3, dt)
|
|
867
|
+
assert sys.getrefcount(singleton) - before == count * 3
|
|
868
|
+
# Fill with `1` and check that it was replaced correctly:
|
|
869
|
+
before2 = sys.getrefcount(one)
|
|
870
|
+
arr[...] = one
|
|
871
|
+
after2 = sys.getrefcount(one)
|
|
872
|
+
assert after2 - before2 == count * 3
|
|
873
|
+
del arr
|
|
874
|
+
gc.collect()
|
|
875
|
+
assert sys.getrefcount(one) == before2
|
|
876
|
+
assert sys.getrefcount(singleton) == before
|
|
877
|
+
|
|
878
|
+
@pytest.mark.parametrize(['dt', 'pat', 'count', 'singleton'],
|
|
879
|
+
iter_struct_object_dtypes())
|
|
880
|
+
@pytest.mark.parametrize(
|
|
881
|
+
['shape', 'index', 'items_changed'],
|
|
882
|
+
[((3,), ([0, 2],), 2),
|
|
883
|
+
((3, 2), ([0, 2], slice(None)), 4),
|
|
884
|
+
((3, 2), ([0, 2], [1]), 2),
|
|
885
|
+
((3,), ([True, False, True]), 2)])
|
|
886
|
+
def test_structured_object_indexing(self, shape, index, items_changed,
|
|
887
|
+
dt, pat, count, singleton):
|
|
888
|
+
"""Structured object reference counting for advanced indexing."""
|
|
889
|
+
# Use two small negative values (should be singletons, but less likely
|
|
890
|
+
# to run into race-conditions). This failed in some threaded envs
|
|
891
|
+
# When using 0 and 1. If it fails again, should remove all explicit
|
|
892
|
+
# checks, and rely on `pytest-leaks` reference count checker only.
|
|
893
|
+
val0 = -4
|
|
894
|
+
val1 = -5
|
|
895
|
+
|
|
896
|
+
arr = np.full(shape, val0, dt)
|
|
897
|
+
|
|
898
|
+
gc.collect()
|
|
899
|
+
before_val0 = sys.getrefcount(val0)
|
|
900
|
+
before_val1 = sys.getrefcount(val1)
|
|
901
|
+
# Test item getting:
|
|
902
|
+
part = arr[index]
|
|
903
|
+
after_val0 = sys.getrefcount(val0)
|
|
904
|
+
assert after_val0 - before_val0 == count * items_changed
|
|
905
|
+
del part
|
|
906
|
+
# Test item setting:
|
|
907
|
+
arr[index] = val1
|
|
908
|
+
gc.collect()
|
|
909
|
+
after_val0 = sys.getrefcount(val0)
|
|
910
|
+
after_val1 = sys.getrefcount(val1)
|
|
911
|
+
assert before_val0 - after_val0 == count * items_changed
|
|
912
|
+
assert after_val1 - before_val1 == count * items_changed
|
|
913
|
+
|
|
914
|
+
@pytest.mark.parametrize(['dt', 'pat', 'count', 'singleton'],
|
|
915
|
+
iter_struct_object_dtypes())
|
|
916
|
+
def test_structured_object_take_and_repeat(self, dt, pat, count, singleton):
|
|
917
|
+
"""Structured object reference counting for specialized functions.
|
|
918
|
+
The older functions such as take and repeat use different code paths
|
|
919
|
+
then item setting (when writing this).
|
|
920
|
+
"""
|
|
921
|
+
indices = [0, 1]
|
|
922
|
+
|
|
923
|
+
arr = np.array([pat] * 3, dt)
|
|
924
|
+
gc.collect()
|
|
925
|
+
before = sys.getrefcount(singleton)
|
|
926
|
+
res = arr.take(indices)
|
|
927
|
+
after = sys.getrefcount(singleton)
|
|
928
|
+
assert after - before == count * 2
|
|
929
|
+
new = res.repeat(10)
|
|
930
|
+
gc.collect()
|
|
931
|
+
after_repeat = sys.getrefcount(singleton)
|
|
932
|
+
assert after_repeat - after == count * 2 * 10
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
class TestStructuredDtypeSparseFields:
|
|
936
|
+
"""Tests subarray fields which contain sparse dtypes so that
|
|
937
|
+
not all memory is used by the dtype work. Such dtype's should
|
|
938
|
+
leave the underlying memory unchanged.
|
|
939
|
+
"""
|
|
940
|
+
dtype = np.dtype([('a', {'names': ['aa', 'ab'], 'formats': ['f', 'f'],
|
|
941
|
+
'offsets': [0, 4]}, (2, 3))])
|
|
942
|
+
sparse_dtype = np.dtype([('a', {'names': ['ab'], 'formats': ['f'],
|
|
943
|
+
'offsets': [4]}, (2, 3))])
|
|
944
|
+
|
|
945
|
+
def test_sparse_field_assignment(self):
|
|
946
|
+
arr = np.zeros(3, self.dtype)
|
|
947
|
+
sparse_arr = arr.view(self.sparse_dtype)
|
|
948
|
+
|
|
949
|
+
sparse_arr[...] = np.finfo(np.float32).max
|
|
950
|
+
# dtype is reduced when accessing the field, so shape is (3, 2, 3):
|
|
951
|
+
assert_array_equal(arr["a"]["aa"], np.zeros((3, 2, 3)))
|
|
952
|
+
|
|
953
|
+
def test_sparse_field_assignment_fancy(self):
|
|
954
|
+
# Fancy assignment goes to the copyswap function for complex types:
|
|
955
|
+
arr = np.zeros(3, self.dtype)
|
|
956
|
+
sparse_arr = arr.view(self.sparse_dtype)
|
|
957
|
+
|
|
958
|
+
sparse_arr[[0, 1, 2]] = np.finfo(np.float32).max
|
|
959
|
+
# dtype is reduced when accessing the field, so shape is (3, 2, 3):
|
|
960
|
+
assert_array_equal(arr["a"]["aa"], np.zeros((3, 2, 3)))
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
class TestMonsterType:
|
|
964
|
+
"""Test deeply nested subtypes."""
|
|
965
|
+
|
|
966
|
+
def test1(self):
|
|
967
|
+
simple1 = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
|
|
968
|
+
'titles': ['Red pixel', 'Blue pixel']})
|
|
969
|
+
a = np.dtype([('yo', int), ('ye', simple1),
|
|
970
|
+
('yi', np.dtype((int, (3, 2))))])
|
|
971
|
+
b = np.dtype([('yo', int), ('ye', simple1),
|
|
972
|
+
('yi', np.dtype((int, (3, 2))))])
|
|
973
|
+
assert_dtype_equal(a, b)
|
|
974
|
+
|
|
975
|
+
c = np.dtype([('yo', int), ('ye', simple1),
|
|
976
|
+
('yi', np.dtype((a, (3, 2))))])
|
|
977
|
+
d = np.dtype([('yo', int), ('ye', simple1),
|
|
978
|
+
('yi', np.dtype((a, (3, 2))))])
|
|
979
|
+
assert_dtype_equal(c, d)
|
|
980
|
+
|
|
981
|
+
@pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
|
|
982
|
+
@pytest.mark.skipif(IS_WASM, reason="Pyodide/WASM has limited stack size")
|
|
983
|
+
def test_list_recursion(self):
|
|
984
|
+
l = []
|
|
985
|
+
l.append(('f', l))
|
|
986
|
+
with pytest.raises(RecursionError):
|
|
987
|
+
np.dtype(l)
|
|
988
|
+
|
|
989
|
+
@pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
|
|
990
|
+
@pytest.mark.skipif(IS_WASM, reason="Pyodide/WASM has limited stack size")
|
|
991
|
+
def test_tuple_recursion(self):
|
|
992
|
+
d = np.int32
|
|
993
|
+
for i in range(100000):
|
|
994
|
+
d = (d, (1,))
|
|
995
|
+
# depending on OS and Python version, this might succeed
|
|
996
|
+
# see gh-30370 and cpython issue #142253
|
|
997
|
+
with contextlib.suppress(RecursionError):
|
|
998
|
+
np.dtype(d)
|
|
999
|
+
|
|
1000
|
+
@pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
|
|
1001
|
+
@pytest.mark.skipif(IS_WASM, reason="Pyodide/WASM has limited stack size")
|
|
1002
|
+
def test_dict_recursion(self):
|
|
1003
|
+
d = {"names": ['self'], "formats": [None], "offsets": [0]}
|
|
1004
|
+
d['formats'][0] = d
|
|
1005
|
+
with pytest.raises(RecursionError):
|
|
1006
|
+
np.dtype(d)
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
class TestMetadata:
|
|
1010
|
+
def test_no_metadata(self):
|
|
1011
|
+
d = np.dtype(int)
|
|
1012
|
+
assert_(d.metadata is None)
|
|
1013
|
+
|
|
1014
|
+
def test_metadata_takes_dict(self):
|
|
1015
|
+
d = np.dtype(int, metadata={'datum': 1})
|
|
1016
|
+
assert_(d.metadata == {'datum': 1})
|
|
1017
|
+
|
|
1018
|
+
def test_metadata_rejects_nondict(self):
|
|
1019
|
+
assert_raises(TypeError, np.dtype, int, metadata='datum')
|
|
1020
|
+
assert_raises(TypeError, np.dtype, int, metadata=1)
|
|
1021
|
+
assert_raises(TypeError, np.dtype, int, metadata=None)
|
|
1022
|
+
|
|
1023
|
+
def test_nested_metadata(self):
|
|
1024
|
+
d = np.dtype([('a', np.dtype(int, metadata={'datum': 1}))])
|
|
1025
|
+
assert_(d['a'].metadata == {'datum': 1})
|
|
1026
|
+
|
|
1027
|
+
def test_base_metadata_copied(self):
|
|
1028
|
+
d = np.dtype((np.void, np.dtype('i4,i4', metadata={'datum': 1})))
|
|
1029
|
+
assert_(d.metadata == {'datum': 1})
|
|
1030
|
+
|
|
1031
|
+
class TestString:
|
|
1032
|
+
def test_complex_dtype_str(self):
|
|
1033
|
+
dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
|
|
1034
|
+
('rtile', '>f4', (64, 36))], (3,)),
|
|
1035
|
+
('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
|
|
1036
|
+
('bright', '>f4', (8, 36))])])
|
|
1037
|
+
assert_equal(str(dt),
|
|
1038
|
+
"[('top', [('tiles', ('>f4', (64, 64)), (1,)), "
|
|
1039
|
+
"('rtile', '>f4', (64, 36))], (3,)), "
|
|
1040
|
+
"('bottom', [('bleft', ('>f4', (8, 64)), (1,)), "
|
|
1041
|
+
"('bright', '>f4', (8, 36))])]")
|
|
1042
|
+
|
|
1043
|
+
# If the sticky aligned flag is set to True, it makes the
|
|
1044
|
+
# str() function use a dict representation with an 'aligned' flag
|
|
1045
|
+
dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
|
|
1046
|
+
('rtile', '>f4', (64, 36))],
|
|
1047
|
+
(3,)),
|
|
1048
|
+
('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
|
|
1049
|
+
('bright', '>f4', (8, 36))])],
|
|
1050
|
+
align=True)
|
|
1051
|
+
assert_equal(str(dt),
|
|
1052
|
+
"{'names': ['top', 'bottom'],"
|
|
1053
|
+
" 'formats': [([('tiles', ('>f4', (64, 64)), (1,)), "
|
|
1054
|
+
"('rtile', '>f4', (64, 36))], (3,)), "
|
|
1055
|
+
"[('bleft', ('>f4', (8, 64)), (1,)), "
|
|
1056
|
+
"('bright', '>f4', (8, 36))]],"
|
|
1057
|
+
" 'offsets': [0, 76800],"
|
|
1058
|
+
" 'itemsize': 80000,"
|
|
1059
|
+
" 'aligned': True}")
|
|
1060
|
+
with np.printoptions(legacy='1.21'):
|
|
1061
|
+
assert_equal(str(dt),
|
|
1062
|
+
"{'names':['top','bottom'], "
|
|
1063
|
+
"'formats':[([('tiles', ('>f4', (64, 64)), (1,)), "
|
|
1064
|
+
"('rtile', '>f4', (64, 36))], (3,)),"
|
|
1065
|
+
"[('bleft', ('>f4', (8, 64)), (1,)), "
|
|
1066
|
+
"('bright', '>f4', (8, 36))]], "
|
|
1067
|
+
"'offsets':[0,76800], "
|
|
1068
|
+
"'itemsize':80000, "
|
|
1069
|
+
"'aligned':True}")
|
|
1070
|
+
assert_equal(np.dtype(eval(str(dt))), dt)
|
|
1071
|
+
|
|
1072
|
+
dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'],
|
|
1073
|
+
'offsets': [0, 1, 2],
|
|
1074
|
+
'titles': ['Red pixel', 'Green pixel', 'Blue pixel']})
|
|
1075
|
+
assert_equal(str(dt),
|
|
1076
|
+
"[(('Red pixel', 'r'), 'u1'), "
|
|
1077
|
+
"(('Green pixel', 'g'), 'u1'), "
|
|
1078
|
+
"(('Blue pixel', 'b'), 'u1')]")
|
|
1079
|
+
|
|
1080
|
+
dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'],
|
|
1081
|
+
'formats': ['<u4', 'u1', 'u1', 'u1'],
|
|
1082
|
+
'offsets': [0, 0, 1, 2],
|
|
1083
|
+
'titles': ['Color', 'Red pixel',
|
|
1084
|
+
'Green pixel', 'Blue pixel']})
|
|
1085
|
+
assert_equal(str(dt),
|
|
1086
|
+
"{'names': ['rgba', 'r', 'g', 'b'],"
|
|
1087
|
+
" 'formats': ['<u4', 'u1', 'u1', 'u1'],"
|
|
1088
|
+
" 'offsets': [0, 0, 1, 2],"
|
|
1089
|
+
" 'titles': ['Color', 'Red pixel', "
|
|
1090
|
+
"'Green pixel', 'Blue pixel'],"
|
|
1091
|
+
" 'itemsize': 4}")
|
|
1092
|
+
|
|
1093
|
+
dt = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
|
|
1094
|
+
'offsets': [0, 2],
|
|
1095
|
+
'titles': ['Red pixel', 'Blue pixel']})
|
|
1096
|
+
assert_equal(str(dt),
|
|
1097
|
+
"{'names': ['r', 'b'],"
|
|
1098
|
+
" 'formats': ['u1', 'u1'],"
|
|
1099
|
+
" 'offsets': [0, 2],"
|
|
1100
|
+
" 'titles': ['Red pixel', 'Blue pixel'],"
|
|
1101
|
+
" 'itemsize': 3}")
|
|
1102
|
+
|
|
1103
|
+
dt = np.dtype([('a', '<m8[D]'), ('b', '<M8[us]')])
|
|
1104
|
+
assert_equal(str(dt),
|
|
1105
|
+
"[('a', '<m8[D]'), ('b', '<M8[us]')]")
|
|
1106
|
+
|
|
1107
|
+
def test_repr_structured(self):
|
|
1108
|
+
dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
|
|
1109
|
+
('rtile', '>f4', (64, 36))], (3,)),
|
|
1110
|
+
('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
|
|
1111
|
+
('bright', '>f4', (8, 36))])])
|
|
1112
|
+
assert_equal(repr(dt),
|
|
1113
|
+
"dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)), "
|
|
1114
|
+
"('rtile', '>f4', (64, 36))], (3,)), "
|
|
1115
|
+
"('bottom', [('bleft', ('>f4', (8, 64)), (1,)), "
|
|
1116
|
+
"('bright', '>f4', (8, 36))])])")
|
|
1117
|
+
|
|
1118
|
+
dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'],
|
|
1119
|
+
'offsets': [0, 1, 2],
|
|
1120
|
+
'titles': ['Red pixel', 'Green pixel', 'Blue pixel']},
|
|
1121
|
+
align=True)
|
|
1122
|
+
assert_equal(repr(dt),
|
|
1123
|
+
"dtype([(('Red pixel', 'r'), 'u1'), "
|
|
1124
|
+
"(('Green pixel', 'g'), 'u1'), "
|
|
1125
|
+
"(('Blue pixel', 'b'), 'u1')], align=True)")
|
|
1126
|
+
|
|
1127
|
+
def test_repr_structured_not_packed(self):
|
|
1128
|
+
dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'],
|
|
1129
|
+
'formats': ['<u4', 'u1', 'u1', 'u1'],
|
|
1130
|
+
'offsets': [0, 0, 1, 2],
|
|
1131
|
+
'titles': ['Color', 'Red pixel',
|
|
1132
|
+
'Green pixel', 'Blue pixel']}, align=True)
|
|
1133
|
+
assert_equal(repr(dt),
|
|
1134
|
+
"dtype({'names': ['rgba', 'r', 'g', 'b'],"
|
|
1135
|
+
" 'formats': ['<u4', 'u1', 'u1', 'u1'],"
|
|
1136
|
+
" 'offsets': [0, 0, 1, 2],"
|
|
1137
|
+
" 'titles': ['Color', 'Red pixel', "
|
|
1138
|
+
"'Green pixel', 'Blue pixel'],"
|
|
1139
|
+
" 'itemsize': 4}, align=True)")
|
|
1140
|
+
|
|
1141
|
+
dt = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
|
|
1142
|
+
'offsets': [0, 2],
|
|
1143
|
+
'titles': ['Red pixel', 'Blue pixel'],
|
|
1144
|
+
'itemsize': 4})
|
|
1145
|
+
assert_equal(repr(dt),
|
|
1146
|
+
"dtype({'names': ['r', 'b'], "
|
|
1147
|
+
"'formats': ['u1', 'u1'], "
|
|
1148
|
+
"'offsets': [0, 2], "
|
|
1149
|
+
"'titles': ['Red pixel', 'Blue pixel'], "
|
|
1150
|
+
"'itemsize': 4})")
|
|
1151
|
+
|
|
1152
|
+
def test_repr_structured_datetime(self):
|
|
1153
|
+
dt = np.dtype([('a', '<M8[D]'), ('b', '<m8[us]')])
|
|
1154
|
+
assert_equal(repr(dt),
|
|
1155
|
+
"dtype([('a', '<M8[D]'), ('b', '<m8[us]')])")
|
|
1156
|
+
|
|
1157
|
+
def test_repr_str_subarray(self):
|
|
1158
|
+
dt = np.dtype(('<i2', (1,)))
|
|
1159
|
+
assert_equal(repr(dt), "dtype(('<i2', (1,)))")
|
|
1160
|
+
assert_equal(str(dt), "('<i2', (1,))")
|
|
1161
|
+
|
|
1162
|
+
def test_base_dtype_with_object_type(self):
|
|
1163
|
+
# Issue gh-2798, should not error.
|
|
1164
|
+
np.array(['a'], dtype="O").astype(("O", [("name", "O")]))
|
|
1165
|
+
|
|
1166
|
+
def test_empty_string_to_object(self):
|
|
1167
|
+
# Pull request #4722
|
|
1168
|
+
np.array(["", ""]).astype(object)
|
|
1169
|
+
|
|
1170
|
+
def test_void_subclass_unsized(self):
|
|
1171
|
+
dt = np.dtype(np.record)
|
|
1172
|
+
assert_equal(repr(dt), "dtype('V')")
|
|
1173
|
+
assert_equal(str(dt), '|V0')
|
|
1174
|
+
assert_equal(dt.name, 'record')
|
|
1175
|
+
|
|
1176
|
+
def test_void_subclass_sized(self):
|
|
1177
|
+
dt = np.dtype((np.record, 2))
|
|
1178
|
+
assert_equal(repr(dt), "dtype('V2')")
|
|
1179
|
+
assert_equal(str(dt), '|V2')
|
|
1180
|
+
assert_equal(dt.name, 'record16')
|
|
1181
|
+
|
|
1182
|
+
def test_void_subclass_fields(self):
|
|
1183
|
+
dt = np.dtype((np.record, [('a', '<u2')]))
|
|
1184
|
+
assert_equal(repr(dt), "dtype((numpy.record, [('a', '<u2')]))")
|
|
1185
|
+
assert_equal(str(dt), "(numpy.record, [('a', '<u2')])")
|
|
1186
|
+
assert_equal(dt.name, 'record16')
|
|
1187
|
+
|
|
1188
|
+
def test_custom_dtype_str(self):
|
|
1189
|
+
dt = np.dtypes.StringDType()
|
|
1190
|
+
assert_equal(dt.str, "StringDType()")
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
class TestDtypeAttributeDeletion:
|
|
1194
|
+
|
|
1195
|
+
def test_dtype_non_writable_attributes_deletion(self):
|
|
1196
|
+
dt = np.dtype(np.double)
|
|
1197
|
+
attr = ["subdtype", "descr", "str", "name", "base", "shape",
|
|
1198
|
+
"isbuiltin", "isnative", "isalignedstruct", "fields",
|
|
1199
|
+
"metadata", "hasobject"]
|
|
1200
|
+
|
|
1201
|
+
for s in attr:
|
|
1202
|
+
assert_raises(AttributeError, delattr, dt, s)
|
|
1203
|
+
|
|
1204
|
+
def test_dtype_writable_attributes_deletion(self):
|
|
1205
|
+
dt = np.dtype(np.double)
|
|
1206
|
+
attr = ["names"]
|
|
1207
|
+
for s in attr:
|
|
1208
|
+
assert_raises(AttributeError, delattr, dt, s)
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
class TestDtypeAttributes:
|
|
1212
|
+
def test_descr_has_trailing_void(self):
|
|
1213
|
+
# see gh-6359
|
|
1214
|
+
dtype = np.dtype({
|
|
1215
|
+
'names': ['A', 'B'],
|
|
1216
|
+
'formats': ['f4', 'f4'],
|
|
1217
|
+
'offsets': [0, 8],
|
|
1218
|
+
'itemsize': 16})
|
|
1219
|
+
new_dtype = np.dtype(dtype.descr)
|
|
1220
|
+
assert_equal(new_dtype.itemsize, 16)
|
|
1221
|
+
|
|
1222
|
+
def test_name_dtype_subclass(self):
|
|
1223
|
+
# Ticket #4357
|
|
1224
|
+
class user_def_subcls(np.void):
|
|
1225
|
+
pass
|
|
1226
|
+
assert_equal(np.dtype(user_def_subcls).name, 'user_def_subcls')
|
|
1227
|
+
|
|
1228
|
+
def test_zero_stride(self):
|
|
1229
|
+
arr = np.ones(1, dtype="i8")
|
|
1230
|
+
arr = np.broadcast_to(arr, 10)
|
|
1231
|
+
assert arr.strides == (0,)
|
|
1232
|
+
with pytest.raises(ValueError):
|
|
1233
|
+
arr.dtype = "i1"
|
|
1234
|
+
|
|
1235
|
+
class TestDTypeMakeCanonical:
|
|
1236
|
+
def check_canonical(self, dtype, canonical):
|
|
1237
|
+
"""
|
|
1238
|
+
Check most properties relevant to "canonical" versions of a dtype,
|
|
1239
|
+
which is mainly native byte order for datatypes supporting this.
|
|
1240
|
+
|
|
1241
|
+
The main work is checking structured dtypes with fields, where we
|
|
1242
|
+
reproduce most the actual logic used in the C-code.
|
|
1243
|
+
"""
|
|
1244
|
+
assert type(dtype) is type(canonical)
|
|
1245
|
+
|
|
1246
|
+
# a canonical DType should always have equivalent casting (both ways)
|
|
1247
|
+
assert np.can_cast(dtype, canonical, casting="equiv")
|
|
1248
|
+
assert np.can_cast(canonical, dtype, casting="equiv")
|
|
1249
|
+
# a canonical dtype (and its fields) is always native (checks fields):
|
|
1250
|
+
assert canonical.isnative
|
|
1251
|
+
|
|
1252
|
+
# Check that canonical of canonical is the same (no casting):
|
|
1253
|
+
assert np.result_type(canonical) == canonical
|
|
1254
|
+
|
|
1255
|
+
if not dtype.names:
|
|
1256
|
+
# The flags currently never change for unstructured dtypes
|
|
1257
|
+
assert dtype.flags == canonical.flags
|
|
1258
|
+
return
|
|
1259
|
+
|
|
1260
|
+
# Must have all the needs API flag set:
|
|
1261
|
+
assert dtype.flags & 0b10000
|
|
1262
|
+
|
|
1263
|
+
# Check that the fields are identical (including titles):
|
|
1264
|
+
assert dtype.fields.keys() == canonical.fields.keys()
|
|
1265
|
+
|
|
1266
|
+
def aligned_offset(offset, alignment):
|
|
1267
|
+
# round up offset:
|
|
1268
|
+
return - (-offset // alignment) * alignment
|
|
1269
|
+
|
|
1270
|
+
totalsize = 0
|
|
1271
|
+
max_alignment = 1
|
|
1272
|
+
for name in dtype.names:
|
|
1273
|
+
# each field is also canonical:
|
|
1274
|
+
new_field_descr = canonical.fields[name][0]
|
|
1275
|
+
self.check_canonical(dtype.fields[name][0], new_field_descr)
|
|
1276
|
+
|
|
1277
|
+
# Must have the "inherited" object related flags:
|
|
1278
|
+
expected = 0b11011 & new_field_descr.flags
|
|
1279
|
+
assert (canonical.flags & expected) == expected
|
|
1280
|
+
|
|
1281
|
+
if canonical.isalignedstruct:
|
|
1282
|
+
totalsize = aligned_offset(totalsize, new_field_descr.alignment)
|
|
1283
|
+
max_alignment = max(new_field_descr.alignment, max_alignment)
|
|
1284
|
+
|
|
1285
|
+
assert canonical.fields[name][1] == totalsize
|
|
1286
|
+
# if a title exists, they must match (otherwise empty tuple):
|
|
1287
|
+
assert dtype.fields[name][2:] == canonical.fields[name][2:]
|
|
1288
|
+
|
|
1289
|
+
totalsize += new_field_descr.itemsize
|
|
1290
|
+
|
|
1291
|
+
if canonical.isalignedstruct:
|
|
1292
|
+
totalsize = aligned_offset(totalsize, max_alignment)
|
|
1293
|
+
assert canonical.itemsize == totalsize
|
|
1294
|
+
assert canonical.alignment == max_alignment
|
|
1295
|
+
|
|
1296
|
+
def test_simple(self):
|
|
1297
|
+
dt = np.dtype(">i4")
|
|
1298
|
+
assert np.result_type(dt).isnative
|
|
1299
|
+
assert np.result_type(dt).num == dt.num
|
|
1300
|
+
|
|
1301
|
+
# dtype with empty space:
|
|
1302
|
+
struct_dt = np.dtype(">i4,<i1,i8,V3")[["f0", "f2"]]
|
|
1303
|
+
canonical = np.result_type(struct_dt)
|
|
1304
|
+
assert canonical.itemsize == 4 + 8
|
|
1305
|
+
assert canonical.isnative
|
|
1306
|
+
|
|
1307
|
+
# aligned struct dtype with empty space:
|
|
1308
|
+
struct_dt = np.dtype(">i1,<i4,i8,V3", align=True)[["f0", "f2"]]
|
|
1309
|
+
canonical = np.result_type(struct_dt)
|
|
1310
|
+
assert canonical.isalignedstruct
|
|
1311
|
+
assert canonical.itemsize == np.dtype("i8").alignment + 8
|
|
1312
|
+
assert canonical.isnative
|
|
1313
|
+
|
|
1314
|
+
def test_object_flag_not_inherited(self):
|
|
1315
|
+
# The following dtype still indicates "object", because its included
|
|
1316
|
+
# in the unaccessible space (maybe this could change at some point):
|
|
1317
|
+
arr = np.ones(3, "i,O,i")[["f0", "f2"]]
|
|
1318
|
+
assert arr.dtype.hasobject
|
|
1319
|
+
canonical_dt = np.result_type(arr.dtype)
|
|
1320
|
+
assert not canonical_dt.hasobject
|
|
1321
|
+
|
|
1322
|
+
@pytest.mark.slow
|
|
1323
|
+
@hypothesis.given(dtype=hynp.nested_dtypes())
|
|
1324
|
+
def test_make_canonical_hypothesis(self, dtype):
|
|
1325
|
+
canonical = np.result_type(dtype)
|
|
1326
|
+
self.check_canonical(dtype, canonical)
|
|
1327
|
+
# result_type with two arguments should always give identical results:
|
|
1328
|
+
two_arg_result = np.result_type(dtype, dtype)
|
|
1329
|
+
assert np.can_cast(two_arg_result, canonical, casting="no")
|
|
1330
|
+
|
|
1331
|
+
@pytest.mark.slow
|
|
1332
|
+
@hypothesis.given(
|
|
1333
|
+
dtype=hypothesis.extra.numpy.array_dtypes(
|
|
1334
|
+
subtype_strategy=hypothesis.extra.numpy.array_dtypes(),
|
|
1335
|
+
min_size=5, max_size=10, allow_subarrays=True),
|
|
1336
|
+
random=hypothesis.strategies.randoms())
|
|
1337
|
+
def test_structured(self, dtype, random):
|
|
1338
|
+
# Pick 4 of the fields at random. This will leave empty space in the
|
|
1339
|
+
# dtype (since we do not canonicalize it here).
|
|
1340
|
+
field_subset = random.sample(dtype.names, k=4)
|
|
1341
|
+
dtype_with_empty_space = dtype[field_subset]
|
|
1342
|
+
assert dtype_with_empty_space.itemsize == dtype.itemsize
|
|
1343
|
+
canonicalized = np.result_type(dtype_with_empty_space)
|
|
1344
|
+
self.check_canonical(dtype_with_empty_space, canonicalized)
|
|
1345
|
+
# promotion with two arguments should always give identical results:
|
|
1346
|
+
two_arg_result = np.promote_types(
|
|
1347
|
+
dtype_with_empty_space, dtype_with_empty_space)
|
|
1348
|
+
assert np.can_cast(two_arg_result, canonicalized, casting="no")
|
|
1349
|
+
|
|
1350
|
+
# Ensure that we also check aligned struct (check the opposite, in
|
|
1351
|
+
# case hypothesis grows support for `align`. Then repeat the test:
|
|
1352
|
+
dtype_aligned = np.dtype(dtype.descr, align=not dtype.isalignedstruct)
|
|
1353
|
+
dtype_with_empty_space = dtype_aligned[field_subset]
|
|
1354
|
+
assert dtype_with_empty_space.itemsize == dtype_aligned.itemsize
|
|
1355
|
+
canonicalized = np.result_type(dtype_with_empty_space)
|
|
1356
|
+
self.check_canonical(dtype_with_empty_space, canonicalized)
|
|
1357
|
+
# promotion with two arguments should always give identical results:
|
|
1358
|
+
two_arg_result = np.promote_types(
|
|
1359
|
+
dtype_with_empty_space, dtype_with_empty_space)
|
|
1360
|
+
assert np.can_cast(two_arg_result, canonicalized, casting="no")
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
class TestPickling:
|
|
1364
|
+
|
|
1365
|
+
def check_pickling(self, dtype):
|
|
1366
|
+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
|
1367
|
+
buf = pickle.dumps(dtype, proto)
|
|
1368
|
+
# The dtype pickling itself pickles `np.dtype` if it is pickled
|
|
1369
|
+
# as a singleton `dtype` should be stored in the buffer:
|
|
1370
|
+
assert b"_DType_reconstruct" not in buf
|
|
1371
|
+
assert b"dtype" in buf
|
|
1372
|
+
pickled = pickle.loads(buf)
|
|
1373
|
+
assert_equal(pickled, dtype)
|
|
1374
|
+
assert_equal(pickled.descr, dtype.descr)
|
|
1375
|
+
if dtype.metadata is not None:
|
|
1376
|
+
assert_equal(pickled.metadata, dtype.metadata)
|
|
1377
|
+
# Check the reconstructed dtype is functional
|
|
1378
|
+
x = np.zeros(3, dtype=dtype)
|
|
1379
|
+
y = np.zeros(3, dtype=pickled)
|
|
1380
|
+
assert_equal(x, y)
|
|
1381
|
+
assert_equal(x[0], y[0])
|
|
1382
|
+
|
|
1383
|
+
@pytest.mark.skipif(not IS_64BIT, reason="test requires 64-bit system")
|
|
1384
|
+
@pytest.mark.xfail(reason="dtype conversion doesn't allow this yet.")
|
|
1385
|
+
def test_pickling_large(self):
|
|
1386
|
+
# The actual itemsize is larger than a c-integer here.
|
|
1387
|
+
dtype = np.dtype(f"({2**31},)i")
|
|
1388
|
+
self.check_pickling(dtype)
|
|
1389
|
+
dtype = np.dtype(f"({2**31},)i", metadata={"a": "b"})
|
|
1390
|
+
self.check_pickling(dtype)
|
|
1391
|
+
|
|
1392
|
+
@pytest.mark.parametrize('t', [int, float, complex, np.int32, str, object,
|
|
1393
|
+
bool])
|
|
1394
|
+
def test_builtin(self, t):
|
|
1395
|
+
self.check_pickling(np.dtype(t))
|
|
1396
|
+
|
|
1397
|
+
def test_structured(self):
|
|
1398
|
+
dt = np.dtype(([('a', '>f4', (2, 1)), ('b', '<f8', (1, 3))], (2, 2)))
|
|
1399
|
+
self.check_pickling(dt)
|
|
1400
|
+
|
|
1401
|
+
def test_structured_aligned(self):
|
|
1402
|
+
dt = np.dtype('i4, i1', align=True)
|
|
1403
|
+
self.check_pickling(dt)
|
|
1404
|
+
|
|
1405
|
+
def test_structured_unaligned(self):
|
|
1406
|
+
dt = np.dtype('i4, i1', align=False)
|
|
1407
|
+
self.check_pickling(dt)
|
|
1408
|
+
|
|
1409
|
+
def test_structured_padded(self):
|
|
1410
|
+
dt = np.dtype({
|
|
1411
|
+
'names': ['A', 'B'],
|
|
1412
|
+
'formats': ['f4', 'f4'],
|
|
1413
|
+
'offsets': [0, 8],
|
|
1414
|
+
'itemsize': 16})
|
|
1415
|
+
self.check_pickling(dt)
|
|
1416
|
+
|
|
1417
|
+
def test_structured_titles(self):
|
|
1418
|
+
dt = np.dtype({'names': ['r', 'b'],
|
|
1419
|
+
'formats': ['u1', 'u1'],
|
|
1420
|
+
'titles': ['Red pixel', 'Blue pixel']})
|
|
1421
|
+
self.check_pickling(dt)
|
|
1422
|
+
|
|
1423
|
+
@pytest.mark.parametrize('base', ['m8', 'M8'])
|
|
1424
|
+
@pytest.mark.parametrize('unit', ['', 'Y', 'M', 'W', 'D', 'h', 'm', 's',
|
|
1425
|
+
'ms', 'us', 'ns', 'ps', 'fs', 'as'])
|
|
1426
|
+
def test_datetime(self, base, unit):
|
|
1427
|
+
dt = np.dtype(f'{base}[{unit}]' if unit else base)
|
|
1428
|
+
self.check_pickling(dt)
|
|
1429
|
+
if unit:
|
|
1430
|
+
dt = np.dtype(f'{base}[7{unit}]')
|
|
1431
|
+
self.check_pickling(dt)
|
|
1432
|
+
|
|
1433
|
+
def test_metadata(self):
|
|
1434
|
+
dt = np.dtype(int, metadata={'datum': 1})
|
|
1435
|
+
self.check_pickling(dt)
|
|
1436
|
+
|
|
1437
|
+
@pytest.mark.parametrize("DType",
|
|
1438
|
+
[type(np.dtype(t)) for t in np.typecodes['All']] +
|
|
1439
|
+
[type(np.dtype(rational)), np.dtype])
|
|
1440
|
+
def test_pickle_dtype_class(self, DType):
|
|
1441
|
+
# Check that DTypes (the classes/types) roundtrip when pickling
|
|
1442
|
+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
|
1443
|
+
roundtrip_DType = pickle.loads(pickle.dumps(DType, proto))
|
|
1444
|
+
assert roundtrip_DType is DType
|
|
1445
|
+
|
|
1446
|
+
@pytest.mark.parametrize("dt",
|
|
1447
|
+
[np.dtype(t) for t in np.typecodes['All']] +
|
|
1448
|
+
[np.dtype(rational)])
|
|
1449
|
+
def test_pickle_dtype(self, dt):
|
|
1450
|
+
# Check that dtype instances roundtrip when pickling and that pickling
|
|
1451
|
+
# doesn't change the hash value
|
|
1452
|
+
pre_pickle_hash = hash(dt)
|
|
1453
|
+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
|
1454
|
+
roundtrip_dt = pickle.loads(pickle.dumps(dt, proto))
|
|
1455
|
+
assert roundtrip_dt == dt
|
|
1456
|
+
assert hash(roundtrip_dt) == pre_pickle_hash
|
|
1457
|
+
|
|
1458
|
+
|
|
1459
|
+
class TestPromotion:
|
|
1460
|
+
"""Test cases related to more complex DType promotions. Further promotion
|
|
1461
|
+
tests are defined in `test_numeric.py`
|
|
1462
|
+
"""
|
|
1463
|
+
@pytest.mark.parametrize(["other", "expected"],
|
|
1464
|
+
[(2**16 - 1, np.complex64),
|
|
1465
|
+
(2**32 - 1, np.complex64),
|
|
1466
|
+
(np.float16(2), np.complex64),
|
|
1467
|
+
(np.float32(2), np.complex64),
|
|
1468
|
+
(np.longdouble(2), np.clongdouble),
|
|
1469
|
+
# Base of the double value to sidestep any rounding issues:
|
|
1470
|
+
(np.longdouble(np.nextafter(1.7e308, 0.)), np.clongdouble),
|
|
1471
|
+
# Additionally use "nextafter" so the cast can't round down:
|
|
1472
|
+
(np.longdouble(np.nextafter(1.7e308, np.inf)), np.clongdouble),
|
|
1473
|
+
# repeat for complex scalars:
|
|
1474
|
+
(np.complex64(2), np.complex64),
|
|
1475
|
+
(np.clongdouble(2), np.clongdouble),
|
|
1476
|
+
# Base of the double value to sidestep any rounding issues:
|
|
1477
|
+
(np.clongdouble(np.nextafter(1.7e308, 0.) * 1j), np.clongdouble),
|
|
1478
|
+
# Additionally use "nextafter" so the cast can't round down:
|
|
1479
|
+
(np.clongdouble(np.nextafter(1.7e308, np.inf)), np.clongdouble),
|
|
1480
|
+
])
|
|
1481
|
+
def test_complex_other_value_based(self, other, expected):
|
|
1482
|
+
# This would change if we modify the value based promotion
|
|
1483
|
+
min_complex = np.dtype(np.complex64)
|
|
1484
|
+
|
|
1485
|
+
res = np.result_type(other, min_complex)
|
|
1486
|
+
assert res == expected
|
|
1487
|
+
# Check the same for a simple ufunc call that uses the same logic:
|
|
1488
|
+
res = np.minimum(other, np.ones(3, dtype=min_complex)).dtype
|
|
1489
|
+
assert res == expected
|
|
1490
|
+
|
|
1491
|
+
@pytest.mark.parametrize(["other", "expected"],
|
|
1492
|
+
[(np.bool, np.complex128),
|
|
1493
|
+
(np.int64, np.complex128),
|
|
1494
|
+
(np.float16, np.complex64),
|
|
1495
|
+
(np.float32, np.complex64),
|
|
1496
|
+
(np.float64, np.complex128),
|
|
1497
|
+
(np.longdouble, np.clongdouble),
|
|
1498
|
+
(np.complex64, np.complex64),
|
|
1499
|
+
(np.complex128, np.complex128),
|
|
1500
|
+
(np.clongdouble, np.clongdouble),
|
|
1501
|
+
])
|
|
1502
|
+
def test_complex_scalar_value_based(self, other, expected):
|
|
1503
|
+
# This would change if we modify the value based promotion
|
|
1504
|
+
complex_scalar = 1j
|
|
1505
|
+
|
|
1506
|
+
res = np.result_type(other, complex_scalar)
|
|
1507
|
+
assert res == expected
|
|
1508
|
+
# Check the same for a simple ufunc call that uses the same logic:
|
|
1509
|
+
res = np.minimum(np.ones(3, dtype=other), complex_scalar).dtype
|
|
1510
|
+
assert res == expected
|
|
1511
|
+
|
|
1512
|
+
def test_complex_pyscalar_promote_rational(self):
|
|
1513
|
+
with pytest.raises(TypeError,
|
|
1514
|
+
match=r".* no common DType exists for the given inputs"):
|
|
1515
|
+
np.result_type(1j, rational)
|
|
1516
|
+
|
|
1517
|
+
with pytest.raises(TypeError,
|
|
1518
|
+
match=r".* no common DType exists for the given inputs"):
|
|
1519
|
+
np.result_type(1j, rational(1, 2))
|
|
1520
|
+
|
|
1521
|
+
@pytest.mark.parametrize("val", [2, 2**32, 2**63, 2**64, 2 * 100])
|
|
1522
|
+
def test_python_integer_promotion(self, val):
|
|
1523
|
+
# If we only pass scalars (mainly python ones!), NEP 50 means
|
|
1524
|
+
# that we get the default integer
|
|
1525
|
+
expected_dtype = np.dtype(int) # the default integer
|
|
1526
|
+
assert np.result_type(val, 0) == expected_dtype
|
|
1527
|
+
# With NEP 50, the NumPy scalar wins though:
|
|
1528
|
+
assert np.result_type(val, np.int8(0)) == np.int8
|
|
1529
|
+
|
|
1530
|
+
@pytest.mark.parametrize(["other", "expected"],
|
|
1531
|
+
[(1, rational), (1., np.float64)])
|
|
1532
|
+
def test_float_int_pyscalar_promote_rational(self, other, expected):
|
|
1533
|
+
# Note that rationals are a bit awkward as they promote with float64
|
|
1534
|
+
# or default ints, but not float16 or uint8/int8 (which looks
|
|
1535
|
+
# inconsistent here). The new promotion fixed this (partially?)
|
|
1536
|
+
assert np.result_type(other, rational) == expected
|
|
1537
|
+
assert np.result_type(other, rational(1, 2)) == expected
|
|
1538
|
+
|
|
1539
|
+
@pytest.mark.parametrize(["dtypes", "expected"], [
|
|
1540
|
+
# These promotions are not associative/commutative:
|
|
1541
|
+
([np.uint16, np.int16, np.float16], np.float32),
|
|
1542
|
+
([np.uint16, np.int8, np.float16], np.float32),
|
|
1543
|
+
([np.uint8, np.int16, np.float16], np.float32),
|
|
1544
|
+
# The following promotions are not ambiguous, but cover code
|
|
1545
|
+
# paths of abstract promotion (no particular logic being tested)
|
|
1546
|
+
([1, 1, np.float64], np.float64),
|
|
1547
|
+
([1, 1., np.complex128], np.complex128),
|
|
1548
|
+
([1, 1j, np.float64], np.complex128),
|
|
1549
|
+
([1., 1., np.int64], np.float64),
|
|
1550
|
+
([1., 1j, np.float64], np.complex128),
|
|
1551
|
+
([1j, 1j, np.float64], np.complex128),
|
|
1552
|
+
([1, True, np.bool], np.int_),
|
|
1553
|
+
])
|
|
1554
|
+
def test_permutations_do_not_influence_result(self, dtypes, expected):
|
|
1555
|
+
# Tests that most permutations do not influence the result. In the
|
|
1556
|
+
# above some uint and int combinations promote to a larger integer
|
|
1557
|
+
# type, which would then promote to a larger than necessary float.
|
|
1558
|
+
for perm in permutations(dtypes):
|
|
1559
|
+
assert np.result_type(*perm) == expected
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
def test_rational_dtype():
|
|
1563
|
+
# test for bug gh-5719
|
|
1564
|
+
a = np.array([1111], dtype=rational).astype
|
|
1565
|
+
assert_raises(OverflowError, a, 'int8')
|
|
1566
|
+
|
|
1567
|
+
# test that dtype detection finds user-defined types
|
|
1568
|
+
x = rational(1)
|
|
1569
|
+
assert_equal(np.array([x, x]).dtype, np.dtype(rational))
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
def test_dtypes_are_true():
|
|
1573
|
+
# test for gh-6294
|
|
1574
|
+
assert bool(np.dtype('f8'))
|
|
1575
|
+
assert bool(np.dtype('i8'))
|
|
1576
|
+
assert bool(np.dtype([('a', 'i8'), ('b', 'f4')]))
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
def test_invalid_dtype_string():
|
|
1580
|
+
# test for gh-10440
|
|
1581
|
+
assert_raises(TypeError, np.dtype, 'f8,i8,[f8,i8]')
|
|
1582
|
+
assert_raises(TypeError, np.dtype, 'Fl\xfcgel')
|
|
1583
|
+
|
|
1584
|
+
|
|
1585
|
+
def test_keyword_argument():
|
|
1586
|
+
# test for https://github.com/numpy/numpy/pull/16574#issuecomment-642660971
|
|
1587
|
+
assert np.dtype(dtype=np.float64) == np.dtype(np.float64)
|
|
1588
|
+
|
|
1589
|
+
|
|
1590
|
+
class TestFromDTypeAttribute:
|
|
1591
|
+
def test_simple(self):
|
|
1592
|
+
class dt:
|
|
1593
|
+
dtype = np.dtype("f8")
|
|
1594
|
+
|
|
1595
|
+
assert np.dtype(dt) == np.float64
|
|
1596
|
+
assert np.dtype(dt()) == np.float64
|
|
1597
|
+
|
|
1598
|
+
def test_recursive(self):
|
|
1599
|
+
# This used to recurse. It now doesn't, we enforce the
|
|
1600
|
+
# dtype attribute to be a dtype (and will not recurse).
|
|
1601
|
+
class dt:
|
|
1602
|
+
pass
|
|
1603
|
+
|
|
1604
|
+
dt.dtype = dt
|
|
1605
|
+
with pytest.raises(ValueError):
|
|
1606
|
+
np.dtype(dt)
|
|
1607
|
+
|
|
1608
|
+
dt_instance = dt()
|
|
1609
|
+
dt_instance.dtype = dt
|
|
1610
|
+
with pytest.raises(ValueError):
|
|
1611
|
+
np.dtype(dt_instance)
|
|
1612
|
+
|
|
1613
|
+
def test_void_subtype(self):
|
|
1614
|
+
class dt(np.void):
|
|
1615
|
+
# This code path is fully untested before, so it is unclear
|
|
1616
|
+
# what this should be useful for. Note that if np.void is used
|
|
1617
|
+
# numpy will think we are deallocating a base type [1.17, 2019-02].
|
|
1618
|
+
dtype = np.dtype("f,f")
|
|
1619
|
+
|
|
1620
|
+
np.dtype(dt)
|
|
1621
|
+
np.dtype(dt(1))
|
|
1622
|
+
|
|
1623
|
+
def test_void_subtype_recursive(self):
|
|
1624
|
+
# Used to recurse, but dtype is now enforced to be a dtype instance
|
|
1625
|
+
# so that we do not recurse.
|
|
1626
|
+
class vdt(np.void):
|
|
1627
|
+
pass
|
|
1628
|
+
|
|
1629
|
+
vdt.dtype = vdt
|
|
1630
|
+
|
|
1631
|
+
with pytest.raises(ValueError):
|
|
1632
|
+
np.dtype(vdt)
|
|
1633
|
+
|
|
1634
|
+
with pytest.raises(ValueError):
|
|
1635
|
+
np.dtype(vdt(1))
|
|
1636
|
+
|
|
1637
|
+
|
|
1638
|
+
class TestFromDTypeProtocol:
|
|
1639
|
+
def test_simple(self):
|
|
1640
|
+
class A:
|
|
1641
|
+
dtype = np.dtype("f8")
|
|
1642
|
+
|
|
1643
|
+
assert np.dtype(A()) == np.dtype(np.float64)
|
|
1644
|
+
|
|
1645
|
+
def test_not_a_dtype(self):
|
|
1646
|
+
# This also prevents coercion as a trivial path, although
|
|
1647
|
+
# a custom error may be nicer.
|
|
1648
|
+
class ArrayLike:
|
|
1649
|
+
__numpy_dtype__ = None
|
|
1650
|
+
dtype = np.dtype("f8")
|
|
1651
|
+
|
|
1652
|
+
with pytest.raises(ValueError, match=".*__numpy_dtype__.*"):
|
|
1653
|
+
np.dtype(ArrayLike())
|
|
1654
|
+
|
|
1655
|
+
def test_prevent_dtype_explicit(self):
|
|
1656
|
+
class ArrayLike:
|
|
1657
|
+
@property
|
|
1658
|
+
def __numpy_dtype__(self):
|
|
1659
|
+
raise RuntimeError("my error!")
|
|
1660
|
+
|
|
1661
|
+
with pytest.raises(RuntimeError, match="my error!"):
|
|
1662
|
+
np.dtype(ArrayLike())
|
|
1663
|
+
|
|
1664
|
+
def test_type_object(self):
|
|
1665
|
+
class TypeWithProperty:
|
|
1666
|
+
@property
|
|
1667
|
+
def __numpy_dtype__(self):
|
|
1668
|
+
raise RuntimeError("not reached")
|
|
1669
|
+
|
|
1670
|
+
# Arbitrary types go to object currently, and the
|
|
1671
|
+
# protocol doesn't prevent that.
|
|
1672
|
+
assert np.dtype(TypeWithProperty) == object
|
|
1673
|
+
|
|
1674
|
+
|
|
1675
|
+
class TestDTypeClasses:
|
|
1676
|
+
@pytest.mark.parametrize("dtype", list(np.typecodes['All']) + [rational])
|
|
1677
|
+
def test_basic_dtypes_subclass_properties(self, dtype):
|
|
1678
|
+
# Note: Except for the isinstance and type checks, these attributes
|
|
1679
|
+
# are considered currently private and may change.
|
|
1680
|
+
dtype = np.dtype(dtype)
|
|
1681
|
+
assert isinstance(dtype, np.dtype)
|
|
1682
|
+
assert type(dtype) is not np.dtype
|
|
1683
|
+
if dtype.type.__name__ != "rational":
|
|
1684
|
+
dt_name = type(dtype).__name__.lower().removesuffix("dtype")
|
|
1685
|
+
if dt_name in {"uint", "int"}:
|
|
1686
|
+
# The scalar names has a `c` attached because "int" is Python
|
|
1687
|
+
# int and that is long...
|
|
1688
|
+
dt_name += "c"
|
|
1689
|
+
sc_name = dtype.type.__name__
|
|
1690
|
+
assert dt_name == sc_name.strip("_")
|
|
1691
|
+
assert type(dtype).__module__ == "numpy.dtypes"
|
|
1692
|
+
|
|
1693
|
+
assert getattr(numpy.dtypes, type(dtype).__name__) is type(dtype)
|
|
1694
|
+
else:
|
|
1695
|
+
assert type(dtype).__name__ == "dtype[rational]"
|
|
1696
|
+
assert type(dtype).__module__ == "numpy"
|
|
1697
|
+
|
|
1698
|
+
assert not type(dtype)._abstract
|
|
1699
|
+
|
|
1700
|
+
# the flexible dtypes and datetime/timedelta have additional parameters
|
|
1701
|
+
# which are more than just storage information, these would need to be
|
|
1702
|
+
# given when creating a dtype:
|
|
1703
|
+
parametric = (np.void, np.str_, np.bytes_, np.datetime64, np.timedelta64)
|
|
1704
|
+
if dtype.type not in parametric:
|
|
1705
|
+
assert not type(dtype)._parametric
|
|
1706
|
+
assert type(dtype)() is dtype
|
|
1707
|
+
else:
|
|
1708
|
+
assert type(dtype)._parametric
|
|
1709
|
+
with assert_raises(TypeError):
|
|
1710
|
+
type(dtype)()
|
|
1711
|
+
|
|
1712
|
+
def test_dtype_superclass(self):
|
|
1713
|
+
assert type(np.dtype) is not type
|
|
1714
|
+
assert isinstance(np.dtype, type)
|
|
1715
|
+
|
|
1716
|
+
assert type(np.dtype).__name__ == "_DTypeMeta"
|
|
1717
|
+
assert type(np.dtype).__module__ == "numpy"
|
|
1718
|
+
assert np.dtype._abstract
|
|
1719
|
+
|
|
1720
|
+
def test_is_numeric(self):
|
|
1721
|
+
all_codes = set(np.typecodes['All'])
|
|
1722
|
+
numeric_codes = set(np.typecodes['AllInteger'] +
|
|
1723
|
+
np.typecodes['AllFloat'] + '?')
|
|
1724
|
+
non_numeric_codes = all_codes - numeric_codes
|
|
1725
|
+
|
|
1726
|
+
for code in numeric_codes:
|
|
1727
|
+
assert type(np.dtype(code))._is_numeric
|
|
1728
|
+
|
|
1729
|
+
for code in non_numeric_codes:
|
|
1730
|
+
assert not type(np.dtype(code))._is_numeric
|
|
1731
|
+
|
|
1732
|
+
@pytest.mark.parametrize("int_", ["UInt", "Int"])
|
|
1733
|
+
@pytest.mark.parametrize("size", [8, 16, 32, 64])
|
|
1734
|
+
def test_integer_alias_names(self, int_, size):
|
|
1735
|
+
DType = getattr(numpy.dtypes, f"{int_}{size}DType")
|
|
1736
|
+
sctype = getattr(numpy, f"{int_.lower()}{size}")
|
|
1737
|
+
assert DType.type is sctype
|
|
1738
|
+
assert DType.__name__.lower().removesuffix("dtype") == sctype.__name__
|
|
1739
|
+
|
|
1740
|
+
@pytest.mark.parametrize("name",
|
|
1741
|
+
["Half", "Float", "Double", "CFloat", "CDouble"])
|
|
1742
|
+
def test_float_alias_names_not_present(self, name):
|
|
1743
|
+
assert not hasattr(numpy.dtypes, f"{name}DType")
|
|
1744
|
+
|
|
1745
|
+
def test_scalar_helper_all_dtypes(self):
|
|
1746
|
+
for dtype in np.dtypes.__all__:
|
|
1747
|
+
dt_class = getattr(np.dtypes, dtype)
|
|
1748
|
+
dt = np.dtype(dt_class)
|
|
1749
|
+
if dt.char not in 'OTVM':
|
|
1750
|
+
assert np._core.multiarray.scalar(dt) == dt.type()
|
|
1751
|
+
elif dt.char == 'V':
|
|
1752
|
+
assert np._core.multiarray.scalar(dt) == dt.type(b'\x00')
|
|
1753
|
+
elif dt.char == 'M':
|
|
1754
|
+
# can't do anything with this without generating ValueError
|
|
1755
|
+
# because 'M' has no units
|
|
1756
|
+
_ = np._core.multiarray.scalar(dt)
|
|
1757
|
+
else:
|
|
1758
|
+
with pytest.raises(TypeError):
|
|
1759
|
+
np._core.multiarray.scalar(dt)
|
|
1760
|
+
|
|
1761
|
+
|
|
1762
|
+
class TestFromCTypes:
|
|
1763
|
+
|
|
1764
|
+
@staticmethod
|
|
1765
|
+
def check(ctype, dtype):
|
|
1766
|
+
dtype = np.dtype(dtype)
|
|
1767
|
+
assert np.dtype(ctype) == dtype
|
|
1768
|
+
assert np.dtype(ctype()) == dtype
|
|
1769
|
+
assert ctypes.sizeof(ctype) == dtype.itemsize
|
|
1770
|
+
|
|
1771
|
+
def test_array(self):
|
|
1772
|
+
c8 = ctypes.c_uint8
|
|
1773
|
+
self.check( 3 * c8, (np.uint8, (3,)))
|
|
1774
|
+
self.check( 1 * c8, (np.uint8, (1,)))
|
|
1775
|
+
self.check( 0 * c8, (np.uint8, (0,)))
|
|
1776
|
+
self.check(1 * (3 * c8), ((np.uint8, (3,)), (1,)))
|
|
1777
|
+
self.check(3 * (1 * c8), ((np.uint8, (1,)), (3,)))
|
|
1778
|
+
|
|
1779
|
+
def test_padded_structure(self):
|
|
1780
|
+
class PaddedStruct(ctypes.Structure):
|
|
1781
|
+
_fields_ = [
|
|
1782
|
+
('a', ctypes.c_uint8),
|
|
1783
|
+
('b', ctypes.c_uint16)
|
|
1784
|
+
]
|
|
1785
|
+
expected = np.dtype([
|
|
1786
|
+
('a', np.uint8),
|
|
1787
|
+
('b', np.uint16)
|
|
1788
|
+
], align=True)
|
|
1789
|
+
self.check(PaddedStruct, expected)
|
|
1790
|
+
|
|
1791
|
+
def test_bit_fields(self):
|
|
1792
|
+
class BitfieldStruct(ctypes.Structure):
|
|
1793
|
+
_fields_ = [
|
|
1794
|
+
('a', ctypes.c_uint8, 7),
|
|
1795
|
+
('b', ctypes.c_uint8, 1)
|
|
1796
|
+
]
|
|
1797
|
+
assert_raises(TypeError, np.dtype, BitfieldStruct)
|
|
1798
|
+
assert_raises(TypeError, np.dtype, BitfieldStruct())
|
|
1799
|
+
|
|
1800
|
+
def test_pointer(self):
|
|
1801
|
+
p_uint8 = ctypes.POINTER(ctypes.c_uint8)
|
|
1802
|
+
assert_raises(TypeError, np.dtype, p_uint8)
|
|
1803
|
+
|
|
1804
|
+
def test_size_t(self):
|
|
1805
|
+
assert np.dtype(np.uintp) is np.dtype("N")
|
|
1806
|
+
self.check(ctypes.c_size_t, np.uintp)
|
|
1807
|
+
|
|
1808
|
+
def test_void_pointer(self):
|
|
1809
|
+
self.check(ctypes.c_void_p, "P")
|
|
1810
|
+
|
|
1811
|
+
def test_union(self):
|
|
1812
|
+
class Union(ctypes.Union):
|
|
1813
|
+
_fields_ = [
|
|
1814
|
+
('a', ctypes.c_uint8),
|
|
1815
|
+
('b', ctypes.c_uint16),
|
|
1816
|
+
]
|
|
1817
|
+
expected = np.dtype({
|
|
1818
|
+
"names": ['a', 'b'],
|
|
1819
|
+
"formats": [np.uint8, np.uint16],
|
|
1820
|
+
"offsets": [0, 0],
|
|
1821
|
+
"itemsize": 2
|
|
1822
|
+
})
|
|
1823
|
+
self.check(Union, expected)
|
|
1824
|
+
|
|
1825
|
+
def test_union_with_struct_packed(self):
|
|
1826
|
+
class Struct(ctypes.Structure):
|
|
1827
|
+
_pack_ = 1
|
|
1828
|
+
_fields_ = [
|
|
1829
|
+
('one', ctypes.c_uint8),
|
|
1830
|
+
('two', ctypes.c_uint32)
|
|
1831
|
+
]
|
|
1832
|
+
|
|
1833
|
+
class Union(ctypes.Union):
|
|
1834
|
+
_fields_ = [
|
|
1835
|
+
('a', ctypes.c_uint8),
|
|
1836
|
+
('b', ctypes.c_uint16),
|
|
1837
|
+
('c', ctypes.c_uint32),
|
|
1838
|
+
('d', Struct),
|
|
1839
|
+
]
|
|
1840
|
+
expected = np.dtype({
|
|
1841
|
+
"names": ['a', 'b', 'c', 'd'],
|
|
1842
|
+
"formats": ['u1', np.uint16, np.uint32, [('one', 'u1'), ('two', np.uint32)]],
|
|
1843
|
+
"offsets": [0, 0, 0, 0],
|
|
1844
|
+
"itemsize": ctypes.sizeof(Union)
|
|
1845
|
+
})
|
|
1846
|
+
self.check(Union, expected)
|
|
1847
|
+
|
|
1848
|
+
def test_union_packed(self):
|
|
1849
|
+
class Struct(ctypes.Structure):
|
|
1850
|
+
_fields_ = [
|
|
1851
|
+
('one', ctypes.c_uint8),
|
|
1852
|
+
('two', ctypes.c_uint32)
|
|
1853
|
+
]
|
|
1854
|
+
_pack_ = 1
|
|
1855
|
+
|
|
1856
|
+
class Union(ctypes.Union):
|
|
1857
|
+
_pack_ = 1
|
|
1858
|
+
_fields_ = [
|
|
1859
|
+
('a', ctypes.c_uint8),
|
|
1860
|
+
('b', ctypes.c_uint16),
|
|
1861
|
+
('c', ctypes.c_uint32),
|
|
1862
|
+
('d', Struct),
|
|
1863
|
+
]
|
|
1864
|
+
expected = np.dtype({
|
|
1865
|
+
"names": ['a', 'b', 'c', 'd'],
|
|
1866
|
+
"formats": ['u1', np.uint16, np.uint32, [('one', 'u1'), ('two', np.uint32)]],
|
|
1867
|
+
"offsets": [0, 0, 0, 0],
|
|
1868
|
+
"itemsize": ctypes.sizeof(Union)
|
|
1869
|
+
})
|
|
1870
|
+
self.check(Union, expected)
|
|
1871
|
+
|
|
1872
|
+
def test_packed_structure(self):
|
|
1873
|
+
class PackedStructure(ctypes.Structure):
|
|
1874
|
+
_pack_ = 1
|
|
1875
|
+
_fields_ = [
|
|
1876
|
+
('a', ctypes.c_uint8),
|
|
1877
|
+
('b', ctypes.c_uint16)
|
|
1878
|
+
]
|
|
1879
|
+
expected = np.dtype([
|
|
1880
|
+
('a', np.uint8),
|
|
1881
|
+
('b', np.uint16)
|
|
1882
|
+
])
|
|
1883
|
+
self.check(PackedStructure, expected)
|
|
1884
|
+
|
|
1885
|
+
def test_large_packed_structure(self):
|
|
1886
|
+
class PackedStructure(ctypes.Structure):
|
|
1887
|
+
_pack_ = 2
|
|
1888
|
+
_fields_ = [
|
|
1889
|
+
('a', ctypes.c_uint8),
|
|
1890
|
+
('b', ctypes.c_uint16),
|
|
1891
|
+
('c', ctypes.c_uint8),
|
|
1892
|
+
('d', ctypes.c_uint16),
|
|
1893
|
+
('e', ctypes.c_uint32),
|
|
1894
|
+
('f', ctypes.c_uint32),
|
|
1895
|
+
('g', ctypes.c_uint8)
|
|
1896
|
+
]
|
|
1897
|
+
expected = np.dtype({
|
|
1898
|
+
"formats": [np.uint8, np.uint16, np.uint8, np.uint16, np.uint32, np.uint32, np.uint8],
|
|
1899
|
+
"offsets": [0, 2, 4, 6, 8, 12, 16],
|
|
1900
|
+
"names": ['a', 'b', 'c', 'd', 'e', 'f', 'g'],
|
|
1901
|
+
"itemsize": 18})
|
|
1902
|
+
self.check(PackedStructure, expected)
|
|
1903
|
+
|
|
1904
|
+
def test_big_endian_structure_packed(self):
|
|
1905
|
+
class BigEndStruct(ctypes.BigEndianStructure):
|
|
1906
|
+
_fields_ = [
|
|
1907
|
+
('one', ctypes.c_uint8),
|
|
1908
|
+
('two', ctypes.c_uint32)
|
|
1909
|
+
]
|
|
1910
|
+
_pack_ = 1
|
|
1911
|
+
expected = np.dtype([('one', 'u1'), ('two', '>u4')])
|
|
1912
|
+
self.check(BigEndStruct, expected)
|
|
1913
|
+
|
|
1914
|
+
def test_little_endian_structure_packed(self):
|
|
1915
|
+
class LittleEndStruct(ctypes.LittleEndianStructure):
|
|
1916
|
+
_fields_ = [
|
|
1917
|
+
('one', ctypes.c_uint8),
|
|
1918
|
+
('two', ctypes.c_uint32)
|
|
1919
|
+
]
|
|
1920
|
+
_pack_ = 1
|
|
1921
|
+
expected = np.dtype([('one', 'u1'), ('two', '<u4')])
|
|
1922
|
+
self.check(LittleEndStruct, expected)
|
|
1923
|
+
|
|
1924
|
+
def test_little_endian_structure(self):
|
|
1925
|
+
class PaddedStruct(ctypes.LittleEndianStructure):
|
|
1926
|
+
_fields_ = [
|
|
1927
|
+
('a', ctypes.c_uint8),
|
|
1928
|
+
('b', ctypes.c_uint16)
|
|
1929
|
+
]
|
|
1930
|
+
expected = np.dtype([
|
|
1931
|
+
('a', '<B'),
|
|
1932
|
+
('b', '<H')
|
|
1933
|
+
], align=True)
|
|
1934
|
+
self.check(PaddedStruct, expected)
|
|
1935
|
+
|
|
1936
|
+
def test_big_endian_structure(self):
|
|
1937
|
+
class PaddedStruct(ctypes.BigEndianStructure):
|
|
1938
|
+
_fields_ = [
|
|
1939
|
+
('a', ctypes.c_uint8),
|
|
1940
|
+
('b', ctypes.c_uint16)
|
|
1941
|
+
]
|
|
1942
|
+
expected = np.dtype([
|
|
1943
|
+
('a', '>B'),
|
|
1944
|
+
('b', '>H')
|
|
1945
|
+
], align=True)
|
|
1946
|
+
self.check(PaddedStruct, expected)
|
|
1947
|
+
|
|
1948
|
+
def test_simple_endian_types(self):
|
|
1949
|
+
self.check(ctypes.c_uint16.__ctype_le__, np.dtype('<u2'))
|
|
1950
|
+
self.check(ctypes.c_uint16.__ctype_be__, np.dtype('>u2'))
|
|
1951
|
+
self.check(ctypes.c_uint8.__ctype_le__, np.dtype('u1'))
|
|
1952
|
+
self.check(ctypes.c_uint8.__ctype_be__, np.dtype('u1'))
|
|
1953
|
+
|
|
1954
|
+
all_types = set(np.typecodes['All'])
|
|
1955
|
+
all_pairs = permutations(all_types, 2)
|
|
1956
|
+
|
|
1957
|
+
@pytest.mark.parametrize("pair", all_pairs)
|
|
1958
|
+
def test_pairs(self, pair):
|
|
1959
|
+
"""
|
|
1960
|
+
Check that np.dtype('x,y') matches [np.dtype('x'), np.dtype('y')]
|
|
1961
|
+
Example: np.dtype('d,I') -> dtype([('f0', '<f8'), ('f1', '<u4')])
|
|
1962
|
+
"""
|
|
1963
|
+
# gh-5645: check that np.dtype('i,L') can be used
|
|
1964
|
+
pair_type = np.dtype('{},{}'.format(*pair))
|
|
1965
|
+
expected = np.dtype([('f0', pair[0]), ('f1', pair[1])])
|
|
1966
|
+
assert_equal(pair_type, expected)
|
|
1967
|
+
|
|
1968
|
+
|
|
1969
|
+
class TestUserDType:
|
|
1970
|
+
@pytest.mark.leaks_references(reason="dynamically creates custom dtype.")
|
|
1971
|
+
@pytest.mark.thread_unsafe(reason="crashes when GIL disabled, dtype setup is thread-unsafe")
|
|
1972
|
+
def test_custom_structured_dtype(self):
|
|
1973
|
+
class mytype:
|
|
1974
|
+
pass
|
|
1975
|
+
|
|
1976
|
+
blueprint = np.dtype([("field", object)])
|
|
1977
|
+
dt = create_custom_field_dtype(blueprint, mytype, 0)
|
|
1978
|
+
assert dt.type == mytype
|
|
1979
|
+
# We cannot (currently) *create* this dtype with `np.dtype` because
|
|
1980
|
+
# mytype does not inherit from `np.generic`. This seems like an
|
|
1981
|
+
# unnecessary restriction, but one that has been around forever:
|
|
1982
|
+
assert np.dtype(mytype) == np.dtype("O")
|
|
1983
|
+
|
|
1984
|
+
if HAS_REFCOUNT:
|
|
1985
|
+
# Create an array and test that memory gets cleaned up (gh-25949)
|
|
1986
|
+
o = object()
|
|
1987
|
+
startcount = sys.getrefcount(o)
|
|
1988
|
+
a = np.array([o], dtype=dt)
|
|
1989
|
+
del a
|
|
1990
|
+
assert sys.getrefcount(o) == startcount
|
|
1991
|
+
|
|
1992
|
+
@pytest.mark.thread_unsafe(reason="crashes when GIL disabled, dtype setup is thread-unsafe")
|
|
1993
|
+
def test_custom_structured_dtype_errors(self):
|
|
1994
|
+
class mytype:
|
|
1995
|
+
pass
|
|
1996
|
+
|
|
1997
|
+
blueprint = np.dtype([("field", object)])
|
|
1998
|
+
|
|
1999
|
+
with pytest.raises(ValueError):
|
|
2000
|
+
# Tests what happens if fields are unset during creation
|
|
2001
|
+
# which is currently rejected due to the containing object
|
|
2002
|
+
# (see PyArray_RegisterDataType).
|
|
2003
|
+
create_custom_field_dtype(blueprint, mytype, 1)
|
|
2004
|
+
|
|
2005
|
+
with pytest.raises(RuntimeError):
|
|
2006
|
+
# Tests that a dtype must have its type field set up to np.dtype
|
|
2007
|
+
# or in this case a builtin instance.
|
|
2008
|
+
create_custom_field_dtype(blueprint, mytype, 2)
|
|
2009
|
+
|
|
2010
|
+
|
|
2011
|
+
class TestClassGetItem:
|
|
2012
|
+
def test_dtype(self) -> None:
|
|
2013
|
+
alias = np.dtype[Any]
|
|
2014
|
+
assert isinstance(alias, types.GenericAlias)
|
|
2015
|
+
assert alias.__origin__ is np.dtype
|
|
2016
|
+
|
|
2017
|
+
@pytest.mark.parametrize("code", np.typecodes["All"])
|
|
2018
|
+
def test_dtype_subclass(self, code: str) -> None:
|
|
2019
|
+
cls = type(np.dtype(code))
|
|
2020
|
+
alias = cls[Any]
|
|
2021
|
+
assert isinstance(alias, types.GenericAlias)
|
|
2022
|
+
assert alias.__origin__ is cls
|
|
2023
|
+
|
|
2024
|
+
@pytest.mark.parametrize("arg_len", range(4))
|
|
2025
|
+
def test_subscript_tuple(self, arg_len: int) -> None:
|
|
2026
|
+
arg_tup = (Any,) * arg_len
|
|
2027
|
+
if arg_len == 1:
|
|
2028
|
+
assert np.dtype[arg_tup]
|
|
2029
|
+
else:
|
|
2030
|
+
with pytest.raises(TypeError):
|
|
2031
|
+
np.dtype[arg_tup]
|
|
2032
|
+
|
|
2033
|
+
def test_subscript_scalar(self) -> None:
|
|
2034
|
+
assert np.dtype[Any]
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
def test_result_type_integers_and_unitless_timedelta64():
|
|
2038
|
+
# Regression test for gh-20077. The following call of `result_type`
|
|
2039
|
+
# would cause a seg. fault.
|
|
2040
|
+
td = np.timedelta64(4)
|
|
2041
|
+
result = np.result_type(0, td)
|
|
2042
|
+
assert_dtype_equal(result, td.dtype)
|
|
2043
|
+
|
|
2044
|
+
|
|
2045
|
+
def test_creating_dtype_with_dtype_class_errors():
|
|
2046
|
+
# Regression test for #25031, calling `np.dtype` with itself segfaulted.
|
|
2047
|
+
with pytest.raises(TypeError, match="Cannot convert np.dtype into a"):
|
|
2048
|
+
np.array(np.ones(10), dtype=np.dtype)
|
|
2049
|
+
|
|
2050
|
+
|
|
2051
|
+
@pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO")
|
|
2052
|
+
@pytest.mark.skipif(IS_PYPY, reason="PyPy does not modify tp_doc")
|
|
2053
|
+
class TestDTypeSignatures:
|
|
2054
|
+
def test_signature_dtype(self):
|
|
2055
|
+
sig = inspect.signature(np.dtype)
|
|
2056
|
+
|
|
2057
|
+
assert len(sig.parameters) == 4
|
|
2058
|
+
|
|
2059
|
+
assert "dtype" in sig.parameters
|
|
2060
|
+
assert sig.parameters["dtype"].kind is inspect.Parameter.POSITIONAL_OR_KEYWORD
|
|
2061
|
+
assert sig.parameters["dtype"].default is inspect.Parameter.empty
|
|
2062
|
+
|
|
2063
|
+
assert "align" in sig.parameters
|
|
2064
|
+
assert sig.parameters["align"].kind is inspect.Parameter.POSITIONAL_OR_KEYWORD
|
|
2065
|
+
assert sig.parameters["align"].default is False
|
|
2066
|
+
|
|
2067
|
+
assert "copy" in sig.parameters
|
|
2068
|
+
assert sig.parameters["copy"].kind is inspect.Parameter.POSITIONAL_OR_KEYWORD
|
|
2069
|
+
assert sig.parameters["copy"].default is False
|
|
2070
|
+
|
|
2071
|
+
# the optional `metadata` parameter has no default, so `**kwargs` must be used
|
|
2072
|
+
assert "kwargs" in sig.parameters
|
|
2073
|
+
assert sig.parameters["kwargs"].kind is inspect.Parameter.VAR_KEYWORD
|
|
2074
|
+
assert sig.parameters["kwargs"].default is inspect.Parameter.empty
|
|
2075
|
+
|
|
2076
|
+
def test_signature_dtype_newbyteorder(self):
|
|
2077
|
+
sig = inspect.signature(np.dtype.newbyteorder)
|
|
2078
|
+
|
|
2079
|
+
assert len(sig.parameters) == 2
|
|
2080
|
+
|
|
2081
|
+
assert "self" in sig.parameters
|
|
2082
|
+
assert sig.parameters["self"].kind is inspect.Parameter.POSITIONAL_ONLY
|
|
2083
|
+
assert sig.parameters["self"].default is inspect.Parameter.empty
|
|
2084
|
+
|
|
2085
|
+
assert "new_order" in sig.parameters
|
|
2086
|
+
assert sig.parameters["new_order"].kind is inspect.Parameter.POSITIONAL_ONLY
|
|
2087
|
+
assert sig.parameters["new_order"].default == "S"
|
|
2088
|
+
|
|
2089
|
+
@pytest.mark.parametrize("typename", np.dtypes.__all__)
|
|
2090
|
+
def test_signature_dtypes_classes(self, typename: str):
|
|
2091
|
+
dtype_type = getattr(np.dtypes, typename)
|
|
2092
|
+
sig = inspect.signature(dtype_type)
|
|
2093
|
+
|
|
2094
|
+
match typename.lower().removesuffix("dtype"):
|
|
2095
|
+
case "bytes" | "str":
|
|
2096
|
+
params_expect = {"size"}
|
|
2097
|
+
case "void":
|
|
2098
|
+
params_expect = {"length"}
|
|
2099
|
+
case "datetime64" | "timedelta64":
|
|
2100
|
+
params_expect = {"unit"}
|
|
2101
|
+
case "string":
|
|
2102
|
+
# `na_object` cannot be used in the text signature because of its
|
|
2103
|
+
# `np._NoValue` default, which isn't supported by `inspect.signature`,
|
|
2104
|
+
# so `**kwargs` is used instead.
|
|
2105
|
+
params_expect = {"coerce", "kwargs"}
|
|
2106
|
+
case _:
|
|
2107
|
+
params_expect = set()
|
|
2108
|
+
|
|
2109
|
+
params_actual = set(sig.parameters)
|
|
2110
|
+
assert params_actual == params_expect
|